package com.authine.cloudpivot.web.api.controller.runtime;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.word.WordUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.authine.cloudpivot.engine.api.facade.TaskReportFacade;
import com.authine.cloudpivot.engine.api.model.application.AppFunctionModel;
import com.authine.cloudpivot.engine.api.model.bizform.BizFormModel;
import com.authine.cloudpivot.engine.api.model.bizmodel.BizPermGroupModel;
import com.authine.cloudpivot.engine.api.model.bizmodel.BizPermPropertyModel;
import com.authine.cloudpivot.engine.api.model.bizmodel.BizPropertyModel;
import com.authine.cloudpivot.engine.api.model.bizmodel.BizSchemaModel;
import com.authine.cloudpivot.engine.api.model.bizquery.*;
import com.authine.cloudpivot.engine.api.model.export.ExportTaskModel;
import com.authine.cloudpivot.engine.api.model.organization.DepartmentModel;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.permission.AppFunctionPermissionModel;
import com.authine.cloudpivot.engine.api.model.permission.AppPackagePermissionModel;
import com.authine.cloudpivot.engine.api.model.permission.PermissionGroupModel;
import com.authine.cloudpivot.engine.api.model.runtime.*;
import com.authine.cloudpivot.engine.api.model.system.RelatedCorpSettingModel;
import com.authine.cloudpivot.engine.component.query.api.FilterExpression;
import com.authine.cloudpivot.engine.component.query.api.Page;
import com.authine.cloudpivot.engine.component.query.api.helper.PageableImpl;
import com.authine.cloudpivot.engine.component.query.api.helper.Q;
import com.authine.cloudpivot.engine.enums.ErrCode;
import com.authine.cloudpivot.engine.enums.status.ExportResultStatus;
import com.authine.cloudpivot.engine.enums.status.ExportTaskStatus;
import com.authine.cloudpivot.engine.enums.status.UserStatus;
import com.authine.cloudpivot.engine.enums.status.WorkflowInstanceStatus;
import com.authine.cloudpivot.engine.enums.type.*;
import com.authine.cloudpivot.web.api.controller.app.BizSchemaController;
import com.authine.cloudpivot.web.api.exception.PortalException;
import com.authine.cloudpivot.web.api.exception.ResultEnum;
import com.authine.cloudpivot.web.api.handler.CustomizedOrigin;
import com.authine.cloudpivot.web.api.helper.ExportExcelHelper;
import com.authine.cloudpivot.web.api.helper.FileOperateHelper;
import com.authine.cloudpivot.web.api.helper.PropertyValidateHelper;
import com.authine.cloudpivot.web.api.service.AtsService;
import com.authine.cloudpivot.web.api.service.StoreService;
import com.authine.cloudpivot.web.api.service.impl.FescoadQueryServiceImpl;
import com.authine.cloudpivot.web.api.util.IdWorker;
import com.authine.cloudpivot.web.api.view.PageVO;
import com.authine.cloudpivot.web.api.view.ResponseResult;
import com.authine.cloudpivot.web.api.view.runtime.FileOperationResult;
import com.authine.cloudpivot.web.api.view.runtime.FilterVO;
import com.authine.cloudpivot.web.api.view.runtime.QueryDataVO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.curator.shaded.com.google.common.base.Joiner;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.time.*;
import java.util.*;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author zhangjie
 * @date 2019-12-09
 */
@Api(value = "定制的查询列表数据接口", tags = "运行时::定制的列表查询接口")
@RestController
@RequestMapping("/api/runtime/query")
@Slf4j
@CustomizedOrigin(level = 1)
public class CustomizedQueryRuntimeController extends QueryRuntimeController {

	private static final String FILE_NAME_NOT_EMPTY = "文件名称不能为空";
	private static final String BIZ_SCHEMA_CODE_NOT_EMPTY = "模型编码不能为空";
	@Value("${cloudpivot.export.data.pageable}")
	private Integer exportDataPageable;
	private static final int PROJECT_MANAGER_ROLE = 1;
	private static final int EXECUTE_DIRECTOR_ROLE = 2;
	private static ExecutorService threadPoolExec = Executors.newFixedThreadPool(2);
	private static CompletionService<ExportTaskModel> completionService = new ExecutorCompletionService<ExportTaskModel>(threadPoolExec);

	@Autowired
	private IdWorker idWorker;

	//excel模板
	private String onLineReportReview = "templates/excelTemplate/xszpzbtb.xlsx";
	private String offLineReportReview = "templates/excelTemplate/xxzpzbtb.xlsx";
	private String offLineReportReview2 = "templates/excelTemplate/xxzpzbtb2.xlsx";
	private String executeReportReview = "templates/excelTemplate/zxzbtj.xlsx";
	private String executeReportReview2 = "templates/excelTemplate/zxzbtj2.xlsx";
	private String storeInfo = "templates/excelTemplate/mdxx.xlsx";

	@Value("spring.profiles.active")
	private String profileActive;

	@Value("${executeMangerRoleId}")
	private String executeMangerRoleId;

	@Value("${executeDirectorRoleId}")
	private String executeDirectorRoleId;

	@Value("${trafficRoleId}")
	private String trafficRoleId;

	@Reference(version = "1.00")
	private TaskReportFacade taskReportFacade;

	@Autowired
	private AtsService atsService;

	@Autowired
	private StoreService storeService;

	@Autowired
	private FescoadQueryServiceImpl fescoadQueryService;

	/**
	 * 列表查询方法
	 * 如果需要定制查询方法，
	 * 需要将QueryDataVO.customized设置为true
	 * （即前端接口参数中将需要将QueryDataVO.customized设置为true）
	 *
	 * @param queryData 查询对象
	 * @return page
	 */
	@ApiOperation(value = "查询数据接口")
	@PostMapping("/list")
	@Override
	public ResponseResult<PageVO<BizObjectModel>> list(@RequestBody QueryDataVO queryData) {

		if(log.isDebugEnabled()) {
			log.debug("query list. customized = [{}]", queryData.isCustomized());
		}

		// 默认执行云枢产品列表查询方法, 请勿修改
		if(!queryData.isCustomized()) {
			return super.list(queryData);
		}

		// TODO 二次开发定制列表查询 ^-^
		// 如果需要定制列表查询方法，请在此处添加具体的实现
		// queryData.getSchemaCode() 数据模型编码
		// queryData.getQueryCode()  列表查询编码
		// 例： 自定义 模型编码schemaCode=test01, 列表查询编码queryCode=qu01 的查询方法
		// 则可以:
		if(log.isDebugEnabled()) {
			log.debug("二次开发代码.");
		}

		String schemaCode = "test01";
		String queryCode = "qu01";
		if(schemaCode.equals(queryData.getSchemaCode()) && queryCode.equals(queryData.getQueryCode())) {

			// TODO 自定义查询代码
			return null;

		} else {

			// TODO 其他自定义代码
			Page<BizObjectModel> data = new Page<BizObjectModel>() {
				@Override
				public long getTotal() {
					return 0;
				}

				@Override
				public List<? extends BizObjectModel> getContent() {
					return Lists.newArrayList();
				}

				@Override
				public Integer getSumLine() {
					return 0;
				}

				@Override
				public Map<String, Object> getSumMap() {
					return Maps.newHashMap();
				}

				@Override
				public void setSumLine(Integer sumLine) {
					this.setSumLine(sumLine);
				}

				@Override
				public void setSumMap(Map<String, Object> sumMap) {
					this.setSumMap(sumMap);
				}
			};
			return this.getOkResponseResult(new PageVO<>(data), "获取数据成功");
		}
	}

	/**
	 * @param queryData
	 * @return
	 */
	@Override
	@ApiOperation(value = "列表数据导出异步执行接口")
	@ApiImplicitParam(name = "queryDataVO", value = "导出数据查询模型", required = true, dataType = "query")
	@PostMapping("/export_data/async")
	public Object asyncExportData(@RequestBody QueryDataVO queryData) {
		ExportTaskModel exportTaskModel = new ExportTaskModel();
		exportTaskModel.setStartTime(new Date());
		exportTaskModel.setTaskStatus(ExportTaskStatus.RUN);
		exportTaskModel.setUserId(getUserId());
		ExportTaskModel entity = getExportTaskFacade().save(exportTaskModel);
		asyncFullExport(queryData, entity);
		return getOkResponseResult(entity, "成功");
	}

	@ApiOperation(value = "列表模板导出接口")
	@PostMapping("/export_template")
	@Override
	public void exportTemplate(@RequestBody Map<String, String> map, HttpServletResponse response) {
		String schemaCode = map.get("schemaCode");
		String ids= map.get("ids");
		List<String> idList = null;
		if(StringUtils.isNotBlank(ids)){
			idList = Arrays.asList(ids.split(","));

		}
		validateCode(schemaCode, BizSchemaController.SCHEMA_CODE_INVALID_MSG);
		final AppFunctionModel functionModel = getAppManagementFacade().getAppFunctionByCode(schemaCode);
		if (functionModel == null) {
			throw new PortalException(ErrCode.APP_FUNCTION_MODEL_NOTEXIST.getErrCode(), ErrCode.APP_FUNCTION_MODEL_NOTEXIST.getErrMsg());
		}

		if("ZPXQZBGL".equals(schemaCode)){
			if(CollectionUtils.isNotEmpty(idList)) {
				String recruitWay = "线上";
				//获取招聘需求id
				idList = taskReportFacade.getRecruitmentIds(idList, recruitWay);
			}
			Page<BizObjectModel> reportDatas =  getReportDate("XSZPZBTJ","XSZPZBTJ",Arrays.asList("postId","year","month","depart","frontOperator","projectName",
					"demandCreatedTime","province","city","areas","area","storeName","operator",
					"address","jobName","postNature","recruitmentType","demandFor","needFinishTime",
					"cycle","communicateNum","inviteNum","toFaceNum","offerNum","entryNum",
					"counselor","onlineRecruitmentNum","clientProvideNum","projectProvideNum","recuitmentId","comment","storeCode"),idList);
			exportReportData(response, reportDatas,"XSZPZBTJ",idList,null);
		}else if("XXZPXQZBGL".equals(schemaCode)){
			if(CollectionUtils.isNotEmpty(idList)) {
				String recruitWay = "线下";
				//获取招聘需求id
				idList = taskReportFacade.getRecruitmentIds(idList, recruitWay);
			}
			Page<BizObjectModel> reportDatas =  getReportDate("XXZPZBTJ","XXZPZBTJ",Arrays.asList("postId","year","month","depart","frontOperator","projectName",
					"demandCreatedTime","province","city","areas","area","storeName","operator",
					"address","jobName","postNature","recruitmentType","demandFor","needFinishTime",
					"cycle","plannedNum","finishedNum","recommendNum","councilor","comment",
					"MGFinishedNum","clientProvideNum","projectProvideNum","recuitmentId","storeCode","resubmisPerson"),idList);
			exportReportData(response, reportDatas,"XXZPZBTJ",idList,null);
		}else if("ZXZBGL".equals(schemaCode)) {
			if(CollectionUtils.isNotEmpty(idList)) {
				//获取执行需求id
				idList = taskReportFacade.getExecuteDemandIds(idList);
			}
			Page<BizObjectModel> reportDatas =  getReportDate("ZXZBMX","ZXZBMX",Arrays.asList("reportCreateTime", "depart","frontOperator","operator","demandCreatedTime",
					"projectName","executeDemandId","activityName","executeId", "year","month","cycle","province","city","area","planRoundNum","planGearsNum","postJD","activityStartTime","activityEndTime",
					"storeNum","actualGearsNum","actualRoundNum","councilor","remark","MGGearsNum","MGRoundNum","projectProvideNum","clientProvideNum","industry","dateRange","resubmisPerson","arePersons","reasonNum"),idList);
			exportReportData(response, reportDatas,"ZXZBMX",idList,null);
		}else if("ZXXQTB".equals(schemaCode)) {
			// idList就是执行需求id
			Page<BizObjectModel> reportDatas = getReportDate("WHMDXX", "WHMDXX", Arrays.asList("id","subjectName", "projectNo", "customerStoreNum", "storeShortName", "storeNum", "rcsArea", "province", "cityName",
					"district", "detailArea", "area", "storeOutlet", "customDockingPerson", "customLinkType", "cityLevel", "storeStatus"), idList);
			if(reportDatas.getTotal() == 0){
				//根据id获取招聘需求提报的相关信息
				BizObjectQueryModel queryModel = new BizObjectQueryModel();
				PageableImpl pageable = new PageableImpl(0, 9999);
				queryModel.setSchemaCode("ZXXQTB");
				queryModel.setQueryCode("ZXXQTB");
				queryModel.setPageable(pageable);
				FilterExpression filterExpression = Q.it("id", FilterExpression.Op.In, idList);
				queryModel.setFilterExpr(filterExpression);
				BizObjectQueryModel.Options option = new BizObjectQueryModel.Options();
				option.setQueryDisplayType(QueryDisplayType.APPEND);
				option.setCustomDisplayColumns(Arrays.asList("id","creater","createdDeptId","demandCreatedTime", "activityStartTime","activityEndTime",
						"operator","postJD","executeDetails","projectName","recruitmentType","frontOperator","operator","activityName", "projectNameStr",
						"industry","qthysm","projectNameStr","jobNature","projectNo"));
				queryModel.setOptions(option);
				reportDatas = getBizObjectFacade().queryBizObjects(queryModel);
				String activityName  = reportDatas.getContent().get(0).getData().get("activityName").toString();
				exportReportData(response,reportDatas,"ZXXQTB",idList,activityName);
			}else{
				//根据id获取招聘需求提报的相关信息
				BizObjectQueryModel queryModel = new BizObjectQueryModel();
				PageableImpl pageable = new PageableImpl(0, 9999);
				queryModel.setSchemaCode("ZXXQTB");
				queryModel.setQueryCode("ZXXQTB");
				queryModel.setPageable(pageable);
				FilterExpression filterExpression = Q.it("id", FilterExpression.Op.In, idList);
				queryModel.setFilterExpr(filterExpression);
				BizObjectQueryModel.Options option = new BizObjectQueryModel.Options();
				option.setQueryDisplayType(QueryDisplayType.APPEND);
				option.setCustomDisplayColumns(Arrays.asList("id","creater","createdDeptId","demandCreatedTime", "activityStartTime","activityEndTime",
						"operator","postJD","executeDetails","projectName","recruitmentType","frontOperator","operator","activityName", "projectNameStr",
						"industry","qthysm","projectNameStr","jobNature","projectNo"));
				queryModel.setOptions(option);
				Page<BizObjectModel> reportDataList = getBizObjectFacade().queryBizObjects(queryModel);
				String activityName  = reportDataList.getContent().get(0).getData().get("activityName").toString();
				exportReportData(response,reportDatas,"ZXXQTB",idList,activityName);
			}
		}else {
			BizSchemaModel bizSchemaModel = getAppManagementFacade().getBizSchemaBySchemaCode(schemaCode, true);
			String name = bizSchemaModel.getName();
			//固定表头加载顺序，先加载非子表数据项->无内容的子表数据项->有内容的子表数据项
			List<BizQueryColumnModel> oldColumns = getColumns(bizSchemaModel);
			List<BizQueryColumnModel> oldHeaderColumns = getHeaderColumns(oldColumns);

			List<BizQueryColumnModel> columns = new ArrayList<>();
			List<BizQueryColumnModel> headerColumns = new ArrayList<>();
			//删除三列name数据标题sequenceNo单据号owner拥有者
			List<String> delete = new ArrayList();
			delete.add("name");
			delete.add("owner");
			delete.add("sequenceNo");
			for (BizQueryColumnModel column : oldColumns) {
				if (!column.getSchemaCode().equals(schemaCode)) {
					columns.add(column);
					continue;
				}
				if (!delete.contains(column.getPropertyCode())) {
					columns.add(column);
				}
			}
			for (BizQueryColumnModel headerColumn : oldHeaderColumns) {
				if (!headerColumn.getSchemaCode().equals(schemaCode)) {
					headerColumns.add(headerColumn);
					continue;
				}
				if (!delete.contains(headerColumn.getPropertyCode())) {
					headerColumns.add(headerColumn);
				}
			}
			if (CollectionUtils.isEmpty(columns)) {
				throw new PortalException(ErrCode.BIZ_QUERY_NOT_EXIST.getErrCode(), "列表配置信息不存在");
			}
			List<String> headers = headerColumns.stream().map(BizQueryColumnModel::getName).collect(Collectors.toList());
			FileOperateHelper.exportData(response, headers, name, null, headerColumns);
		}
	}


	private void exportReportData(HttpServletResponse response, Page<BizObjectModel> reportDatas, String schemaCode, List<String> idList,String activityName) {
		if("XXZPZBTJ".equals(schemaCode)){
			String fileName = "";
			boolean isExecuteManger = taskReportFacade.hasRole(getUserId(),executeMangerRoleId);
			boolean isExecuteDirector = taskReportFacade.hasRole(getUserId(),executeDirectorRoleId);

			if(!isExecuteDirector){
				isExecuteDirector = taskReportFacade.hasRole(getUserId(),trafficRoleId);
			}

			XSSFWorkbook wb = null;
			// 输出流
			OutputStream os = null;
			try {
				if( !(isExecuteManger ^ isExecuteDirector)) {
					wb = new XSSFWorkbook(WordUtil.class.getClassLoader().getResourceAsStream(offLineReportReview));
					XSSFSheet sheet = wb.getSheetAt(0);
					int rowIndex = 4;
					for (BizObjectModel reportModel : reportDatas.getContent()) {
						Map<String, Object> data = reportModel.getData();
						sheet.createRow(rowIndex);
						setCellStrValue(sheet, rowIndex, 1, ((HashMap<String, Object>) data.get("recuitmentId")).get("id").toString());
						setCellStrValue(sheet, rowIndex, 2, MapUtils.getString(data, "postId"));
						setCellStrValue(sheet, rowIndex, 3, MapUtils.getString(data, "year"));
						setCellStrValue(sheet, rowIndex, 4, MapUtils.getString(data, "month"));
						setCellStrValue(sheet, rowIndex, 5, ((ArrayList<SelectionValue>)data.get("depart")).get(0).getName());
						setCellStrValue(sheet, rowIndex, 6, ((ArrayList<SelectionValue>)data.get("frontOperator")).get(0).getName());
						setCellStrValue(sheet, rowIndex, 7, (data.get("operator") == null ? null : ((ArrayList<SelectionValue>)data.get("operator")).get(0).getName()));
						setCellStrValue(sheet, rowIndex, 8, ((HashMap<String,Object>)data.get("projectName")).get("projectNames").toString());
						String demandCreatedTime = DateFormatUtils.format((Date) data.get("demandCreatedTime"), "yyyy-MM-dd");
						setCellStrValue(sheet, rowIndex, 9, demandCreatedTime);
						setCellStrValue(sheet, rowIndex, 10, MapUtils.getString(data, "storeCode"));
						setCellStrValue(sheet, rowIndex, 11, MapUtils.getString(data, "rcsArea"));

						setCellStrValue(sheet, rowIndex, 12, MapUtils.getString(data, "province"));
						setCellStrValue(sheet, rowIndex, 13, MapUtils.getString(data, "city"));
						setCellStrValue(sheet, rowIndex, 14, MapUtils.getString(data, "areas"));
						setCellStrValue(sheet, rowIndex, 15, MapUtils.getString(data, "storeName"));
						setCellStrValue(sheet, rowIndex, 16, MapUtils.getString(data, "address"));
						setCellStrValue(sheet, rowIndex, 17, ((HashMap<String,Object>)data.get("jobName")).get("jobName").toString());
						setCellStrValue(sheet, rowIndex, 18, MapUtils.getString(data, "postNature"));
						setCellStrValue(sheet, rowIndex, 19, MapUtils.getString(data, "recruitmentType"));
						setCellStrValue(sheet, rowIndex, 20, MapUtils.getDouble(data, "demandFor"));

						String needFinishTime = DateFormatUtils.format((Date) data.get("needFinishTime"), "yyyy-MM-dd");
						setCellStrValue(sheet, rowIndex, 21, needFinishTime);
						setCellStrValue(sheet, rowIndex, 22, MapUtils.getString(data, "cycle"));
						setCellStrValue(sheet, rowIndex, 23, MapUtils.getDouble(data, "finishedNum"));
						setCellStrValue(sheet, rowIndex, 24, MapUtils.getDouble(data, "plannedNum"));
						setCellStrValue(sheet, rowIndex, 25, MapUtils.getDouble(data, "recommendNum"));
						setCellStrValue(sheet, rowIndex, 26, MapUtils.getString(data, "councilor"));
						setCellStrValue(sheet, rowIndex, 27, MapUtils.getString(data, "comment"));

						if(MapUtils.getDouble(data, "MGFinishedNum") != null) {
							setCellStrValue(sheet, rowIndex, 28, MapUtils.getDouble(data, "MGFinishedNum"));
						}else {
							if ("不确定人数".equals(MapUtils.getString(data, "recruitmentType"))) {
								setCellStrValue(sheet, rowIndex, 28, MapUtils.getDouble(data, "recommendNum"));
							} else {
								setCellStrValue(sheet, rowIndex, 28, MapUtils.getDouble(data, "finishedNum"));
							}
						}

						setCellStrValue(sheet, rowIndex, 29, MapUtils.getDouble(data, "clientProvideNum"));
						setCellStrValue(sheet, rowIndex, 30, MapUtils.getDouble(data, "projectProvideNum"));
						setCellStrValue(sheet,rowIndex, 31, MapUtils.getString(data, "id"));
						if(data.get("resubmisPerson")!= null) {
							setCellStrValue(sheet, rowIndex, 32,  ((ArrayList<SelectionValue>) data.get("resubmisPerson")).get(0).getName());
						}
						rowIndex++;
					}
					fileName = "线下招聘周报-项目组复核" + System.currentTimeMillis() + ".xlsx";
				}else {
					wb = new XSSFWorkbook(WordUtil.class.getClassLoader().getResourceAsStream(offLineReportReview2));
					XSSFSheet sheet = wb.getSheetAt(0);
					int rowIndex = 4;
					for (BizObjectModel reportModel : reportDatas.getContent()) {
						Map<String, Object> data = reportModel.getData();
						sheet.createRow(rowIndex);
						setCellStrValue(sheet, rowIndex, 1, ((HashMap<String, Object>) data.get("recuitmentId")).get("id").toString());
						setCellStrValue(sheet, rowIndex, 2, MapUtils.getString(data, "postId"));
						setCellStrValue(sheet, rowIndex, 3, MapUtils.getString(data, "year"));
						setCellStrValue(sheet, rowIndex, 4, MapUtils.getString(data, "month"));
						setCellStrValue(sheet, rowIndex, 5, ((ArrayList<SelectionValue>)data.get("depart")).get(0).getName());
						setCellStrValue(sheet, rowIndex, 6, ((ArrayList<SelectionValue>)data.get("frontOperator")).get(0).getName());
						setCellStrValue(sheet, rowIndex, 7, (data.get("operator") == null ? null : ((ArrayList<SelectionValue>)data.get("operator")).get(0).getName()));
						setCellStrValue(sheet, rowIndex, 8, ((HashMap<String,Object>)data.get("projectName")).get("projectNames").toString());
						String demandCreatedTime = DateFormatUtils.format((Date) data.get("demandCreatedTime"), "yyyy-MM-dd");
						setCellStrValue(sheet, rowIndex, 9, demandCreatedTime);
						setCellStrValue(sheet, rowIndex, 10, MapUtils.getString(data, "storeCode"));
						setCellStrValue(sheet, rowIndex, 11, MapUtils.getString(data, "rcsArea"));

						setCellStrValue(sheet, rowIndex, 12, MapUtils.getString(data, "province"));
						setCellStrValue(sheet, rowIndex, 13, MapUtils.getString(data, "city"));
						setCellStrValue(sheet, rowIndex, 14, MapUtils.getString(data, "areas"));
						setCellStrValue(sheet, rowIndex, 15, MapUtils.getString(data, "storeName"));
						setCellStrValue(sheet, rowIndex, 16, MapUtils.getString(data, "address"));
						setCellStrValue(sheet, rowIndex, 17, ((HashMap<String,Object>)data.get("jobName")).get("jobName").toString());
						setCellStrValue(sheet, rowIndex, 18, MapUtils.getString(data, "postNature"));
						setCellStrValue(sheet, rowIndex, 19, MapUtils.getString(data, "recruitmentType"));
						setCellStrValue(sheet, rowIndex, 20, MapUtils.getDouble(data, "demandFor"));
						String needFinishTime = DateFormatUtils.format((Date) data.get("needFinishTime"), "yyyy-MM-dd");
						setCellStrValue(sheet, rowIndex, 21, needFinishTime);
						setCellStrValue(sheet, rowIndex, 22, MapUtils.getString(data, "cycle"));
						setCellStrValue(sheet, rowIndex, 23, MapUtils.getDouble(data, "finishedNum"));
						setCellStrValue(sheet, rowIndex, 24, MapUtils.getDouble(data, "plannedNum"));
						setCellStrValue(sheet, rowIndex, 25, MapUtils.getDouble(data, "recommendNum"));
						setCellStrValue(sheet, rowIndex, 26, MapUtils.getString(data, "councilor"));
						setCellStrValue(sheet, rowIndex, 27, MapUtils.getString(data, "comment"));
						setCellStrValue(sheet,rowIndex, 28, MapUtils.getString(data, "id"));
						if(data.get("resubmisPerson")!= null) {
							setCellStrValue(sheet, rowIndex, 29,  ((ArrayList<SelectionValue>) data.get("resubmisPerson")).get(0).getName());
						}
						rowIndex++;
					}
					fileName = "线下招聘周报-执行填报" + System.currentTimeMillis() + ".xlsx";
				}
				response.reset();
				response.setContentType("application/octet-stream");//设置生成的文件类型
				response.setCharacterEncoding("UTF-8");//设置文件头编码方式和文件名
				response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
				response.setHeader("Access-Control-Allow-Origin", "*");
				os = response.getOutputStream();
				wb.write(os);
				os.flush();
				wb.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				if(wb != null){
					try {
						wb.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if(os != null){
					try {
						os.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}

		}else if("XSZPZBTJ".equals(schemaCode)){
			XSSFWorkbook wb = null;
			// 输出流
			OutputStream os = null;
			try {
				wb = new XSSFWorkbook(WordUtil.class.getClassLoader().getResourceAsStream(onLineReportReview));
				XSSFSheet sheet = wb.getSheetAt(0);
				int rowIndex = 4;
				for (BizObjectModel  reportModel: reportDatas.getContent()) {
					Map<String,Object> data = reportModel.getData();
					sheet.createRow(rowIndex);
					setCellStrValue(sheet,rowIndex,1,((HashMap<String, Object>) data.get("recuitmentId")).get("id").toString());
					setCellStrValue(sheet,rowIndex,2, MapUtils.getString(data,"postId"));
					setCellStrValue(sheet,rowIndex,3, MapUtils.getString(data,"year"));
					setCellStrValue(sheet,rowIndex,4, MapUtils.getString(data,"month"));
					setCellStrValue(sheet,rowIndex,5, ((ArrayList<SelectionValue>)data.get("depart")).get(0).getName());
					setCellStrValue(sheet,rowIndex,6, ((ArrayList<SelectionValue>)data.get("frontOperator")).get(0).getName());
					setCellStrValue(sheet, rowIndex, 7, (data.get("operator") == null ? null : ((ArrayList<SelectionValue>)data.get("operator")).get(0).getName()));
					setCellStrValue(sheet,rowIndex,8, ((HashMap<String,Object>)data.get("projectName")).get("projectNames").toString());
					String demandCreatedTime = DateFormatUtils.format((Date) data.get("demandCreatedTime"), "yyyy-MM-dd");
					setCellStrValue(sheet,rowIndex,9, demandCreatedTime);
					setCellStrValue(sheet,rowIndex,10, MapUtils.getString(data,"province"));
					setCellStrValue(sheet,rowIndex,11, MapUtils.getString(data,"city"));
					setCellStrValue(sheet,rowIndex,12, MapUtils.getString(data,"areas"));
					setCellStrValue(sheet,rowIndex,13, MapUtils.getString(data,"rcsArea"));
					setCellStrValue(sheet,rowIndex,14, MapUtils.getString(data,"storeName"));
					setCellStrValue(sheet,rowIndex,15, MapUtils.getString(data,"address"));
					setCellStrValue(sheet,rowIndex,16, ((HashMap<String,Object>)data.get("jobName")).get("jobName").toString());
					setCellStrValue(sheet,rowIndex,17, MapUtils.getString(data,"postNature"));
					setCellStrValue(sheet,rowIndex,18, MapUtils.getString(data,"recruitmentType"));
					setCellStrValue(sheet,rowIndex,19, MapUtils.getDouble(data,"demandFor"));
					String needFinishTime = DateFormatUtils.format((Date) data.get("needFinishTime"), "yyyy-MM-dd");
					setCellStrValue(sheet,rowIndex,20, needFinishTime);
					setCellStrValue(sheet,rowIndex,21, MapUtils.getString(data,"cycle"));
					setCellStrValue(sheet,rowIndex,22, MapUtils.getDouble(data,"communicateNum"));
					setCellStrValue(sheet,rowIndex,23, MapUtils.getDouble(data,"inviteNum"));
					setCellStrValue(sheet,rowIndex,24, MapUtils.getDouble(data,"toFaceNum"));
					setCellStrValue(sheet,rowIndex,25, MapUtils.getDouble(data,"offerNum"));
					setCellStrValue(sheet,rowIndex,26, MapUtils.getDouble(data,"entryNum"));
					setCellStrValue(sheet,rowIndex,27, MapUtils.getString(data,"counselor"));
					setCellStrValue(sheet,rowIndex,28, MapUtils.getDouble(data,"onlineRecruitmentNum"));
					//setCellStrValue(sheet,rowIndex,29, MapUtils.getDouble(data,"clientProvideNum"));
					setCellStrValue(sheet,rowIndex,29, MapUtils.getDouble(data,"projectProvideNum"));
					setCellStrValue(sheet,rowIndex, 30, MapUtils.getString(data, "comment"));
					setCellStrValue(sheet,rowIndex, 31, MapUtils.getString(data, "id"));
					rowIndex ++;
				}
				String fileName = "线上招聘周报-项目组复核"+ System.currentTimeMillis() +".xlsx";
				response.reset();
				response.setContentType("application/octet-stream");//设置生成的文件类型
				response.setCharacterEncoding("UTF-8");//设置文件头编码方式和文件名
				response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
				response.setHeader("Access-Control-Allow-Origin", "*");
				os = response.getOutputStream();
				wb.write(os);
				os.flush();
				wb.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				if(wb != null){
					try {
						wb.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if(os != null){
					try {
						os.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}else if("ZXZBMX".equals(schemaCode)){
			String fileName = "";
			boolean isExecuteManger = taskReportFacade.hasRole(getUserId(),executeMangerRoleId);
			boolean isExecuteDirector = taskReportFacade.hasRole(getUserId(),executeDirectorRoleId);

			if(!isExecuteDirector){
				isExecuteDirector = taskReportFacade.hasRole(getUserId(),trafficRoleId);
			}
			XSSFWorkbook wb = null;
			// 输出流
			OutputStream os = null;
			try {
				if( !(isExecuteManger ^ isExecuteDirector)) {
					wb = new XSSFWorkbook(WordUtil.class.getClassLoader().getResourceAsStream(executeReportReview));
					XSSFSheet sheet = wb.getSheetAt(0);
					int rowIndex = 4;
					for (BizObjectModel reportModel : reportDatas.getContent()) {
						Map<String, Object> data = reportModel.getData();
						sheet.createRow(rowIndex);
						setCellStrValue(sheet, rowIndex, 1, MapUtils.getString(data, "year"));
						setCellStrValue(sheet, rowIndex, 2, MapUtils.getString(data, "month"));
						setCellStrValue(sheet, rowIndex, 3, MapUtils.getString(data, "dateRange"));
						setCellStrValue(sheet, rowIndex, 4, ((ArrayList<SelectionValue>)data.get("depart")).get(0).getName());
						setCellStrValue(sheet, rowIndex, 5, ((HashMap<String,Object>)data.get("projectName")).get("projectNames").toString());
						setCellStrValue(sheet, rowIndex, 6, MapUtils.getString(data, "industry"));
						setCellStrValue(sheet, rowIndex, 7, MapUtils.getString(data, "activityName"));
						setCellStrValue(sheet, rowIndex, 8, MapUtils.getString(data, "postJD"));
						setCellStrValue(sheet, rowIndex, 9, ((ArrayList<SelectionValue>)data.get("frontOperator")).get(0).getName());
						setCellStrValue(sheet, rowIndex, 10, (data.get("operator") == null ? null : ((ArrayList<SelectionValue>)data.get("operator")).get(0).getName()));
						setCellStrValue(sheet, rowIndex, 11, DateFormatUtils.format((Date) data.get("activityStartTime"), "yyyy-MM-dd"));
						setCellStrValue(sheet, rowIndex, 12, DateFormatUtils.format((Date) data.get("activityEndTime"), "yyyy-MM-dd"));
						setCellStrValue(sheet, rowIndex, 13, MapUtils.getString(data, "area"));
						setCellStrValue(sheet, rowIndex, 14, MapUtils.getString(data, "province"));
						setCellStrValue(sheet, rowIndex, 15, MapUtils.getString(data, "city"));
						setCellStrValue(sheet, rowIndex, 16, MapUtils.getString(data, "cycle"));
						setCellStrValue(sheet, rowIndex, 17, MapUtils.getDouble(data, "storeNum"));
						setCellStrValue(sheet, rowIndex, 18, MapUtils.getDouble(data, "planGearsNum"));
						setCellStrValue(sheet, rowIndex, 19, MapUtils.getDouble(data, "planRoundNum"));
						setCellStrValue(sheet, rowIndex, 20, MapUtils.getDouble(data, "actualGearsNum"));
						setCellStrValue(sheet, rowIndex, 21, MapUtils.getDouble(data, "actualRoundNum"));
						setCellStrValue(sheet, rowIndex, 22, MapUtils.getString(data, "councilor"));

						setCellStrValue(sheet, rowIndex, 23, (data.get("arePersons") == null ? null : ((ArrayList<SelectionValue>)data.get("arePersons")).get(0).getName()));
						setCellStrValue(sheet, rowIndex, 24, MapUtils.getDouble(data, "reasonNum"));
						setCellStrValue(sheet, rowIndex, 25, MapUtils.getString(data, "remark"));
						if(data.get("MGGearsNum") == null) {
							setCellStrValue(sheet, rowIndex, 26, MapUtils.getDouble(data, "actualGearsNum"));
						}else{
							setCellStrValue(sheet, rowIndex, 26, MapUtils.getDouble(data, "MGGearsNum"));
						}

						if(data.get("MGRoundNum") == null) {
							setCellStrValue(sheet, rowIndex, 27, MapUtils.getDouble(data, "actualRoundNum"));
						}else{
							setCellStrValue(sheet, rowIndex, 27, MapUtils.getDouble(data, "MGRoundNum"));
						}
						setCellStrValue(sheet, rowIndex, 28, MapUtils.getDouble(data, "projectProvideNum"));
						setCellStrValue(sheet, rowIndex, 29, MapUtils.getDouble(data, "clientProvideNum"));
						setCellStrValue(sheet, rowIndex, 30, MapUtils.getString(data, "executeId"));
						setCellStrValue(sheet, rowIndex, 31, ((HashMap<String, Object>) data.get("executeDemandId")).get("id").toString());
						if(data.get("resubmisPerson")!= null) {
							setCellStrValue(sheet, rowIndex, 32,  ((ArrayList<SelectionValue>) data.get("resubmisPerson")).get(0).getName());
						}
						rowIndex++;
					}
					fileName = "执行周报-项目组复核" + System.currentTimeMillis() + ".xlsx";
				}else {
					wb = new XSSFWorkbook(WordUtil.class.getClassLoader().getResourceAsStream(executeReportReview2));
					XSSFSheet sheet = wb.getSheetAt(0);
					int rowIndex = 4;
					for (BizObjectModel reportModel : reportDatas.getContent()) {
						Map<String, Object> data = reportModel.getData();
						sheet.createRow(rowIndex);
						//setCellStrValue(sheet, rowIndex, 1, ((HashMap<String, Object>) data.get("executeDemandId")).get("id").toString());
						setCellStrValue(sheet, rowIndex, 1, MapUtils.getString(data, "year"));
						setCellStrValue(sheet, rowIndex, 2, MapUtils.getString(data, "month"));
						setCellStrValue(sheet, rowIndex, 3, MapUtils.getString(data, "dateRange"));
						setCellStrValue(sheet, rowIndex, 4, ((ArrayList<SelectionValue>)data.get("depart")).get(0).getName());
						setCellStrValue(sheet, rowIndex, 5, ((HashMap<String,Object>)data.get("projectName")).get("projectNames").toString());
						setCellStrValue(sheet, rowIndex, 6, MapUtils.getString(data, "industry"));
						setCellStrValue(sheet, rowIndex, 7, MapUtils.getString(data, "activityName"));
						setCellStrValue(sheet, rowIndex, 8, MapUtils.getString(data, "postJD"));
						setCellStrValue(sheet, rowIndex, 9, ((ArrayList<SelectionValue>)data.get("frontOperator")).get(0).getName());
						setCellStrValue(sheet, rowIndex, 10, (data.get("operator") == null ? null : ((ArrayList<SelectionValue>)data.get("operator")).get(0).getName()));
						setCellStrValue(sheet, rowIndex, 11, DateFormatUtils.format((Date) data.get("activityStartTime"), "yyyy-MM-dd"));
						setCellStrValue(sheet, rowIndex, 12, DateFormatUtils.format((Date) data.get("activityEndTime"), "yyyy-MM-dd"));
						setCellStrValue(sheet, rowIndex, 13, MapUtils.getString(data, "area"));
						setCellStrValue(sheet, rowIndex, 14, MapUtils.getString(data, "province"));
						setCellStrValue(sheet, rowIndex, 15, MapUtils.getString(data, "city"));
						setCellStrValue(sheet, rowIndex, 16, MapUtils.getString(data, "cycle"));
						setCellStrValue(sheet, rowIndex, 17, MapUtils.getDouble(data, "storeNum"));
						setCellStrValue(sheet, rowIndex, 18, MapUtils.getDouble(data, "planGearsNum"));
						setCellStrValue(sheet, rowIndex, 19, MapUtils.getDouble(data, "planRoundNum"));
						setCellStrValue(sheet, rowIndex, 20, MapUtils.getDouble(data, "actualGearsNum"));
						setCellStrValue(sheet, rowIndex, 21, MapUtils.getDouble(data, "actualRoundNum"));
						setCellStrValue(sheet, rowIndex, 22, MapUtils.getString(data, "councilor"));

						setCellStrValue(sheet, rowIndex, 23, (data.get("arePersons") == null ? null : ((ArrayList<SelectionValue>)data.get("arePersons")).get(0).getName()));
						setCellStrValue(sheet, rowIndex, 24, MapUtils.getDouble(data, "reasonNum"));
						setCellStrValue(sheet, rowIndex, 25, MapUtils.getString(data, "remark"));
						setCellStrValue(sheet, rowIndex, 26, MapUtils.getString(data, "executeId"));
						setCellStrValue(sheet, rowIndex, 27, ((HashMap<String, Object>) data.get("executeDemandId")).get("id").toString());
						if(data.get("resubmisPerson")!= null) {
							setCellStrValue(sheet, rowIndex, 28,  ((ArrayList<SelectionValue>) data.get("resubmisPerson")).get(0).getName());
						}
						rowIndex++;
					}
					fileName = "执行周报-执行填报" + System.currentTimeMillis() + ".xlsx";
				}
				response.reset();
				response.setContentType("application/octet-stream");//设置生成的文件类型
				response.setCharacterEncoding("UTF-8");//设置文件头编码方式和文件名
				response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
				response.setHeader("Access-Control-Allow-Origin", "*");
				os = response.getOutputStream();
				wb.write(os);
				os.flush();
				wb.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				if(wb != null){
					try {
						wb.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if(os != null){
					try {
						os.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}else if("ZXXQTB".equals(schemaCode)){
			XSSFWorkbook wb = null;
			// 输出流
			OutputStream os = null;
			try {
				wb = new XSSFWorkbook(WordUtil.class.getClassLoader().getResourceAsStream(storeInfo));
				XSSFSheet sheet = wb.getSheetAt(0);
				int rowIndex = 4;
				String executeDemand = idList.get(0);
				for (BizObjectModel  reportModel: reportDatas.getContent()) {
					Map<String,Object> data = reportModel.getData();
					sheet.createRow(rowIndex);
					setCellStrValue(sheet,rowIndex,2, MapUtils.getString(data,"projectNo"));
					String projectName = null;
					if(data.get("subjectName") != null){
						projectName = ((HashMap<String,Object>)data.get("subjectName")).get("projectNames").toString();
						setCellStrValue(sheet,rowIndex,17, MapUtils.getString(data,"id"));
						setCellStrValue(sheet,rowIndex,1, executeDemand);
					}else{
						setCellStrValue(sheet,rowIndex,1, MapUtils.getString(data,"id"));
						projectName = ((HashMap<String,Object>)data.get("projectName")).get("projectNames").toString();
						setCellStrValue(sheet,rowIndex,17, "");
					}
					setCellStrValue(sheet,rowIndex,3, projectName);
					setCellStrValue(sheet,rowIndex,4, activityName);
					setCellStrValue(sheet,rowIndex,5, MapUtils.getString(data,"customerStoreNum"));
					setCellStrValue(sheet,rowIndex,6, MapUtils.getString(data,"province"));
					setCellStrValue(sheet,rowIndex,7, MapUtils.getString(data,"cityName"));
					setCellStrValue(sheet,rowIndex,8, MapUtils.getString(data,"district"));
					setCellStrValue(sheet,rowIndex,9, MapUtils.getString(data,"storeShortName"));
					setCellStrValue(sheet,rowIndex,10, MapUtils.getString(data,"detailArea"));
					setCellStrValue(sheet,rowIndex,11, MapUtils.getString(data,"area"));
					setCellStrValue(sheet,rowIndex,12, MapUtils.getString(data,"cityLevel"));
					setCellStrValue(sheet,rowIndex,13, MapUtils.getString(data,"customDockingPerson"));
					setCellStrValue(sheet,rowIndex,14, MapUtils.getString(data,"customLinkType"));
					setCellStrValue(sheet,rowIndex,15, MapUtils.getString(data,"storeOutlet"));
					setCellStrValue(sheet,rowIndex,16, MapUtils.getString(data,"storeStatus"));
					rowIndex ++;
				}
				String fileName = "门店信息导入"+ System.currentTimeMillis() +".xlsx";
				response.reset();
				response.setContentType("application/octet-stream");//设置生成的文件类型
				response.setCharacterEncoding("UTF-8");//设置文件头编码方式和文件名
				response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
				response.setHeader("Access-Control-Allow-Origin", "*");
				os = response.getOutputStream();
				wb.write(os);
				os.flush();
				wb.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				if(wb != null){
					try {
						wb.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if(os != null){
					try {
						os.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	private String convertToString(Cell cell){
		if(cell != null) {
			if ("STRING".equals(cell.getCellType().name())) {
				return cell.getStringCellValue();
			} else if ("NUMERIC".equals(cell.getCellType().name())) {
				return (BigDecimal.valueOf(cell.getNumericCellValue())).stripTrailingZeros().toString();
			}
		}
		return "";
	}


	private void setCellStrValue(XSSFSheet sheet, int rowIndex, int cellnum, String value) {
		if(value != null) {
			XSSFCell cell = sheet.getRow(rowIndex).createCell(cellnum);
			cell.setCellValue(value);
		}
	}

	private void setCellStrValue(XSSFSheet sheet, int rowIndex, int cellnum, Double value) {
		if(value != null) {
			XSSFCell cell = sheet.getRow(rowIndex).createCell(cellnum);
			cell.setCellValue(value);
		}
	}

	private Page<BizObjectModel> getReportDate(String schemaCode, String queryCode, List<String> options, List<String> idList){
		String userId = getUserId();
		// 查询对应的位置id
		BizObjectQueryModel queryModel = new BizObjectQueryModel();
		PageableImpl pageable = new PageableImpl(0, 9999);
		queryModel.setSchemaCode(schemaCode);
		queryModel.setQueryCode(queryCode);
		queryModel.setPageable(pageable);
		boolean isExecuteManger = taskReportFacade.hasRole(userId,executeMangerRoleId);
		boolean isExecuteDirector = taskReportFacade.hasRole(userId,executeDirectorRoleId);

		if(!isExecuteDirector){
			isExecuteDirector = taskReportFacade.hasRole(getUserId(),trafficRoleId);
		}
		FilterExpression storeFilterExpression = null;
		if("XXZPZBTJ".equals(schemaCode) && (isExecuteManger || isExecuteDirector)){
			FilterExpression createrFilter = null;
			FilterExpression startTimeFilter = null;
			FilterExpression endTimeFilter =null;
			if(isExecuteManger){
				createrFilter = Q.it("operator", FilterExpression.Op.Like, userId);
				//startTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Gte, getThisMonday());
				//endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt,  getNextMonday());
				startTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Gte, getLastMonday());
				endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt,  getThisMonday());
			}else {
				startTimeFilter = Q.it("isPigeonholed", FilterExpression.Op.Eq, "未归档");
				//startTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Gte, getStartTime(EXECUTE_DIRECTOR_ROLE));
				//endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt, getNextMonday());
				endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt,  getThisMonday());
			}

			if(CollectionUtils.isNotEmpty(idList)){
				FilterExpression idFilter = Q.it("recuitmentId", FilterExpression.Op.In, idList);
				if(createrFilter != null) {
					storeFilterExpression = Q.and(Arrays.asList(createrFilter, startTimeFilter, endTimeFilter, idFilter));
				}else{
					storeFilterExpression = Q.and(Arrays.asList(startTimeFilter, endTimeFilter, idFilter));
				}
			}else{
				if(createrFilter != null) {
					storeFilterExpression = Q.and(Arrays.asList(createrFilter, startTimeFilter, endTimeFilter));
				}else{
					storeFilterExpression = Q.and(Arrays.asList(startTimeFilter, endTimeFilter));
				}
			}
		} else if("ZXZBMX".equals(schemaCode)){
			if((isExecuteManger || isExecuteDirector)){
				FilterExpression createrFilter = null;
				FilterExpression startTimeFilter = null;
				FilterExpression endTimeFilter =null;
				if(isExecuteManger){
					createrFilter = Q.it("operator", FilterExpression.Op.Like, userId);
					//startTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Gte, getThisMonday());
					//endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt, getNextMonday());
					startTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Gte, getLastMonday());
					endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt,  getThisMonday());
				}else {
					//未归档
					//isPigeonholed
					startTimeFilter = Q.it("isPigeonholed", FilterExpression.Op.Eq, "未归档");
					//startTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Gte, getStartTime(EXECUTE_DIRECTOR_ROLE));
					endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt,  getThisMonday());
					//endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt, getNextMonday());
				}

				if(CollectionUtils.isNotEmpty(idList)){
					FilterExpression idFilter = Q.it("executeDemandId", FilterExpression.Op.In, idList);
					if(createrFilter != null) {
						storeFilterExpression = Q.and(Arrays.asList(createrFilter, startTimeFilter, endTimeFilter, idFilter));
					}else{
						storeFilterExpression = Q.and(Arrays.asList(startTimeFilter, endTimeFilter, idFilter));
					}
				}else{
					if(createrFilter != null) {
						storeFilterExpression = Q.and(Arrays.asList(createrFilter, startTimeFilter, endTimeFilter));
					}else{
						storeFilterExpression = Q.and(Arrays.asList(startTimeFilter, endTimeFilter));
					}
				}
			}else{
				//FilterExpression createrFilter = Q.it("creater", FilterExpression.Op.Eq, userId);

				FilterExpression startTimeFilter = Q.it("isPigeonholed", FilterExpression.Op.Eq, "未归档");
				//FilterExpression startTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Gte, getStartTime(PROJECT_MANAGER_ROLE));
				//FilterExpression endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lte, getNextMonday());
				FilterExpression endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt,  getThisMonday());
				if(CollectionUtils.isNotEmpty(idList)){
					FilterExpression idFilter = Q.it("executeDemandId", FilterExpression.Op.In, idList);
					storeFilterExpression = Q.and( Arrays.asList( startTimeFilter, endTimeFilter,idFilter));
				}else{
					storeFilterExpression = Q.and(Arrays.asList(startTimeFilter, endTimeFilter));
				}
			}
		}else if("WHMDXX".equals(schemaCode)){
			String id = idList.get(0);
			storeFilterExpression = Q.it("zxDemand", FilterExpression.Op.Like, id);
		} else {
			//加上项目经理逻辑
			FilterExpression createrFilter = Q.it("creater", FilterExpression.Op.Eq, userId);
			String subjectPersonValue = String.format("[{\"id\":\"%s\",\"type\":3}]", userId);
			FilterExpression subjectPerson = Q.it("subjectPerson", FilterExpression.Op.Eq, subjectPersonValue);
			FilterExpression.Or or = Q.or(Lists.newArrayList(createrFilter,subjectPerson));

			FilterExpression startTimeFilter = Q.it("isPigeonholed", FilterExpression.Op.Eq, "未归档");
			//FilterExpression startTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Gte, getStartTime(PROJECT_MANAGER_ROLE));
			FilterExpression endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lt,  getThisMonday());
			//FilterExpression endTimeFilter = Q.it("reportCreateTime", FilterExpression.Op.Lte, getNextMonday());

			if(CollectionUtils.isNotEmpty(idList)){
				FilterExpression idFilter = Q.it("recuitmentId", FilterExpression.Op.In, idList);
				storeFilterExpression = Q.and( Arrays.asList(or, startTimeFilter, endTimeFilter,idFilter));
			}else{
				storeFilterExpression = Q.and(Arrays.asList(or, startTimeFilter, endTimeFilter));
			}
		}
		queryModel.setFilterExpr(storeFilterExpression);
		BizObjectQueryModel.Options option = new BizObjectQueryModel.Options();
		option.setQueryDisplayType(QueryDisplayType.APPEND);
		option.setCustomDisplayColumns( options);
		queryModel.setOptions(option);
		Page<BizObjectModel> reportDatas = getBizObjectFacade().queryBizObjects(queryModel);
		return reportDatas;
	}

	public static Date getLastMonday(){
		//本周周一
		LocalDateTime nowMonday = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).with(DayOfWeek.MONDAY).minusWeeks(1);
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = nowMonday.atZone(zone).toInstant();
		Date dateime = Date.from(instant);
		return Date.from(instant);

	}

	public static Date getThisMonday(){
		//本周周一
		LocalDateTime nowMonday = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).with(DayOfWeek.MONDAY);
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = nowMonday.atZone(zone).toInstant();
		Date dateime = Date.from(instant);
		return Date.from(instant);

	}



	public static Date getNextMonday(){
		LocalDateTime nextMonday = LocalDateTime.of(LocalDate.now(),LocalTime.MIN).plusWeeks(1).with(DayOfWeek.MONDAY);
		//周一（第一天）
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = nextMonday.atZone(zone).toInstant();
		Date dateime = Date.from(instant);
		return Date.from(instant);
	}



	/**
	 * 获取查询周报的开始时间
	 * @return
	 */
	public static Date getStartTime(int userRole){
		LocalDateTime now= LocalDateTime.now();
		LocalDateTime startTime = LocalDateTime.of(now.getYear(), now.getMonth(), 1, 0, 0,0);
		if(userRole == PROJECT_MANAGER_ROLE) {
			if (!now.isAfter(LocalDateTime.of(now.getYear(), now.getMonth(), 20, 23, 59, 59))) {
				startTime = startTime.minusMonths(1);
			}

		}else if((userRole == EXECUTE_DIRECTOR_ROLE)){
			if (!now.isAfter(LocalDateTime.of(now.getYear(), now.getMonth(), 7, 23, 59, 59))) {
				startTime = startTime.minusMonths(1);
			}
		}
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = startTime.atZone(zone).toInstant();
		java.util.Date startDateTime = Date.from(instant);
		return startDateTime;
	}


	@ApiOperation(value = "列表数据导入接口")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "fileName", value = "模型编码", required = true, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "schemaCode", value = "模型编码", required = true, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "queryCode", value = "列表编码", required = false, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "queryField", value = "查询字段", required = false, dataType = "String", paramType = "query")
	})
	@GetMapping("/import_data")
	@Override
	public ResponseResult<FileOperationResult> importData(@NotBlank(message = FILE_NAME_NOT_EMPTY) @RequestParam String fileName,
														  @NotBlank(message = BIZ_SCHEMA_CODE_NOT_EMPTY) @RequestParam String schemaCode,
														  @RequestParam(required = false) String queryCode,
														  @RequestParam(required = false) String queryField) {

		String userId = this.getUserId();
		log.debug("用户id为={}", userId);
		FileOperationResult fileOperationResult = new FileOperationResult();
		fileOperationResult.setSuccessCount(0);
		fileOperationResult.setErrorCount(0);
		fileOperationResult.setOperationResult(true);
		mapFileOperateInfo.remove(userId);
		if("ZPXQZBGL".equals(schemaCode)){ //线上招聘周报提交复核
			importData(fileOperationResult, fileName, schemaCode,null);
			mapFileOperateInfo.put(userId, fileOperationResult);
			return this.getOkResponseResult(fileOperationResult, fileOperationResult.getErrorMsg());
		}else if("XXZPXQZBGL".equals(schemaCode)){
			importData(fileOperationResult, fileName, schemaCode, null);
			mapFileOperateInfo.put(userId, fileOperationResult);
			return this.getOkResponseResult(fileOperationResult, fileOperationResult.getErrorMsg());
		}else if("ZXZBGL".equals(schemaCode)){
			importData(fileOperationResult, fileName, schemaCode, null);
			mapFileOperateInfo.put(userId, fileOperationResult);
			return this.getOkResponseResult(fileOperationResult, fileOperationResult.getErrorMsg());
		}else if("ZXXQTB".equals(schemaCode)){
			importData(fileOperationResult, fileName, schemaCode, queryField);
			mapFileOperateInfo.put(userId, fileOperationResult);
			return this.getOkResponseResult(fileOperationResult, fileOperationResult.getErrorMsg());
		}else {
			this.customizedCmportDatas(userId, fileName, schemaCode, queryCode, queryField);
			return this.getOkResponseResult(fileOperationResult, "操作成功");
		}

	}

	private void importData(FileOperationResult fileOperationResult, String fileName, String subSchemaCode,String queryField) {
		FileInputStream fileInputStream=null;
		try {
			File file = FileOperateHelper.getFile(fileName);
			fileInputStream = new FileInputStream(file);
			Workbook wb = new XSSFWorkbook(fileInputStream);
			Sheet sheet = wb.getSheetAt(0);
			//获取实际数据项值
			updateReportInfo(fileOperationResult, sheet,subSchemaCode, queryField);
		} catch (IOException e) {
			log.error("", e);
		} finally {
			//删除临时文件 added in 2020-05-18
			if(fileInputStream!=null){
				try {
					fileInputStream.close();
				} catch (IOException e) {
					log.warn(e.getMessage(), e);
				}
			}
			FileOperateHelper.deleteFile(fileName);
		}
	}

	private  void updateReportInfo(FileOperationResult fileOperationResult, Sheet sheet, String subSchemaCode, String queryField) {
		boolean isExecuteManger = taskReportFacade.hasRole(getUserId(),executeMangerRoleId);
		boolean isExecuteDirector = taskReportFacade.hasRole(getUserId(),executeDirectorRoleId);
		if(!isExecuteDirector){
			isExecuteDirector = taskReportFacade.hasRole(getUserId(),trafficRoleId);
		}
		boolean isNeedExecute = false;
		if(isExecuteManger || isExecuteDirector){
			isNeedExecute = true;
		}
		List<Map<String, Object>> maps = new ArrayList<>();
		Set<String> set = new HashSet<>();
		Set<String> demandIdSet = new HashSet<>();
		checkNum(fileOperationResult, maps,set,demandIdSet, sheet, subSchemaCode, isNeedExecute);
		if(fileOperationResult.getErrorType() == 0) {
			//线下复核
			String sheetName = sheet.getSheetName();
			if("线上招聘周报-项目组复核".equals(sheetName)||"线下招聘周报-项目组复核".equals(sheetName)){
//				isNeedExecute = true; // 这个导致复核与填报逻辑相反了
			}
			//执行需求提报
			updateStoreInfo(maps,subSchemaCode,queryField);
			updateReportInfo(maps, demandIdSet, subSchemaCode, isNeedExecute);
			updateReportMgrInfo(subSchemaCode, demandIdSet, isNeedExecute);
		}
		// 增加prod 方便本地调试
		if("prod".equals(profileActive) && !isNeedExecute && (!"ZXXQTB".equals(subSchemaCode))){
			//通知执行经理
			sendMessageToExecutor(maps,subSchemaCode);
		}
	}

	private void sendMessageToExecutor(List<Map<String, Object>> maps, String subSchemaCode) {
		Map<String, List<Map<String,Object>>> mapList = new HashMap<>();
		for(Map<String, Object> map : maps){
			String demandId = map.get("demandId").toString();
			if(mapList.containsKey(demandId)){
				mapList.get(demandId).add(map);
			}else{
				List<Map<String,Object>>  listMap = new ArrayList<>();
				listMap.add(map);
				mapList.put(demandId,listMap);
			}
		}
		for(String demandId : mapList.keySet()){
			Map<String, String> map = taskReportFacade.getDemandInfo(demandId,subSchemaCode);
			List<Map<String, Object>> listMap = mapList.get(demandId);
			Set<String> sbSet = new HashSet<>();
			for(Map<String,Object> tempMap : listMap){
				String sb = tempMap.get("year").toString()+"-"+tempMap.get("month").toString() +"-"+ tempMap.get("cycle").toString()+",";
				sbSet.add(sb);
			}
			String name = map.get("name");
			String operator = map.get("operator").split("\"")[3];
			String result = name+"项目"+StringUtils.join(sbSet,",")+"的周报已经复核！";
			System.out.println(result);
			//"e6779e56684142f5a49321b10226db54"
			fescoadQueryService.sendTextMessage(operator,"",result,"项目复核");
		}
	}

	/**
	 * 执行需求提报
	 * @param maps
	 * @param subSchemaCode
	 * @param queryField
	 */
	private void updateStoreInfo(List<Map<String, Object>> maps, String subSchemaCode, String queryField) {
		if("ZXXQTB".equals(subSchemaCode)){
			String executeDemand = null;
			String subjectName  = null;
			String demandId = null;
			if(maps.size() > 0 ){
				executeDemand = maps.get(0).get("executeDemand") == null ? null:  maps.get(0).get("executeDemand").toString();
				subjectName = maps.get(0).get("subjectName") == null ? null:  maps.get(0).get("subjectName").toString();
				demandId = maps.get(0).get("executeDemand") == null ? null : maps.get(0).get("executeDemand").toString();
			}
			if("true".equals(queryField)){
				if(StringUtils.isNotBlank(executeDemand)) {
					taskReportFacade.delStoreByExecuteId(executeDemand);
				}
			}else{
				maps = maps.stream().filter(item-> item.get("id") == null || StringUtils.isBlank(item.get("id").toString())).collect(Collectors.toList());
			}

			if(maps.size() > 0 ){
				// 根据项目id查询所有门店
				BizObjectQueryModel queryStoreModel = new BizObjectQueryModel();
				PageableImpl pageable = new PageableImpl(0, 9999);
				queryStoreModel.setSchemaCode("WHMDXX");
				queryStoreModel.setQueryCode("WHMDXX");
				queryStoreModel.setPageable(pageable);
				FilterExpression storeFilter = Q.it("subjectName", FilterExpression.Op.Eq, subjectName);
				queryStoreModel.setFilterExpr(storeFilter);
				Page<BizObjectModel> storeInfoDatas = getBizObjectFacade().queryBizObjects(queryStoreModel);
				List<? extends BizObjectModel> storeModels = storeInfoDatas.getContent();
				Set<String> storeNos = storeModels.stream().map(item -> (String)item.getData().get("customerStoreNum")).collect(Collectors.toSet());
				List<Map<String,Object>> unContainsStores = maps.stream().filter(item -> !storeNos.contains((String) item.get("customerStoreNum"))).collect(Collectors.toList());
				unContainsStores.forEach(item->{
					//新增该门店信息
					BizObjectModel bizObjectModel = new BizObjectModel();
					bizObjectModel.setSchemaCode("WHMDXX");
					bizObjectModel.setFormCode("WHMDXX");
					bizObjectModel.setSequenceStatus("COMPLETED");
					Map<String, Object> data = bizObjectModel.getData();
					String name = item.get("storeName") != null ? "门店信息-" + item.get("storeName").toString() : null;
					data.put("name", name);
					data.put("customerStoreNum",item.get("customerStoreNum"));
					data.put("customDockingPerson",item.get("customDockingPerson"));
					data.put("customLinkType",item.get("customLinkType"));
					data.put("storeShortName", item.get("storeShortName"));
					data.put("cityLevel",item.get("cityLevel"));
					data.put("province", item.get("province"));
					data.put("cityName", item.get("cityName"));
					String storeStatus =  item.get("storeStatus") == null || StringUtils.isBlank(item.get("storeStatus").toString()) ? "启用" : item.get("storeStatus").toString();
					data.put("storeStatus", storeStatus);
					data.put("detailArea", item.get("detailArea"));
					data.put("area", item.get("area"));
					data.put("rcsArea",item.get("rcsArea"));
					data.put("district", item.get("district"));
					data.put("storeOutlet", item.get("storeOutlet"));
					data.put("projectNo",item.get("projectNo"));
					data.put("subjectName",item.get("subjectName"));
					data.put("storeNum", storeService.getNextStoreNum());
					//data.put("activityName", item.get("activityName"));
					data.put("zxDemand",item.get("executeDemand"));
					data.put("zxCount",1);

					getBizObjectFacade().saveBizObject(getUserId(), bizObjectModel, false);
				});

				List<Map<String,Object>> containsStores = maps.stream().filter(item -> storeNos.contains((String) item.get("customerStoreNum"))).collect(Collectors.toList());
				if(CollectionUtils.isNotEmpty(containsStores)) {
					taskReportFacade.updateStoreInfo(demandId, subjectName, containsStores, "zx");
				}

				//taskReportFacade.updateRCSAreaByExecuteId(executeDemand);
				taskReportFacade.updateAttrStatusByExecuteId(executeDemand);
			}
		}
	}

	private void updateReportMgrInfo(String subSchemaCode, Set<String> recruitmentIdSet, boolean isNeedExecute) {
		if("ZPXQZBGL".equals(subSchemaCode)){
			for(String recuitmentId : recruitmentIdSet){
				taskReportFacade.updateReportMgrInfo(recuitmentId,"线上",isNeedExecute);
			}
		}else if("XXZPXQZBGL".equals(subSchemaCode)) {
			for(String recuitmentId : recruitmentIdSet){
				taskReportFacade.updateReportMgrInfo(recuitmentId,"线下",isNeedExecute);
			}
		}
	}

	private void updateReportInfo(List<Map<String, Object>> maps, Set <String> demandIdSet, String subSchemaCode, boolean isNeedExecute) {
		if("ZPXQZBGL".equals(subSchemaCode)){
			for(Map<String,Object> map : maps) {
				String id = map.get("id").toString();
				double onlineRecruitmentNum = (double) map.get("onlineRecruitmentNum");
				double projectProvideNum = (double)map.get("projectProvideNum");
				String comment = (String)map.get("comment");
				taskReportFacade.updateOnlineReportInfo(onlineRecruitmentNum,projectProvideNum,comment,id);
			}
		}else if("XXZPXQZBGL".equals(subSchemaCode)) {
			if (isNeedExecute) {
				for (Map<String, Object> map : maps) {
					String id = map.get("id").toString();
					String resubmisPerson = map.get("resubmisPerson").toString();
					double plannedNum = (double) map.get("plannedNum");
					double finishedNum = (double) map.get("finishedNum");
					double recommendNum = (double) map.get("recommendNum");
					String councilor = map.get("councilor").toString();
					String comment = map.get("comment").toString();
					taskReportFacade.updateOffLineReport(plannedNum, finishedNum, recommendNum, councilor, comment, resubmisPerson, id);
				}
			} else {
				for (Map<String, Object> map : maps) {
					String id = map.get("id").toString();
					double MGFinishedNum = (double) map.get("MGFinishedNum");
					double clientProvideNum = (double) map.get("clientProvideNum");
					double projectProvideNum = (double) map.get("projectProvideNum");
					taskReportFacade.updateOffLineReportInfo(MGFinishedNum, clientProvideNum, projectProvideNum,  id);
				}

			}
		}else if("ZXZBGL".equals(subSchemaCode)) {
			if (isNeedExecute) {
				//Map resultMapFromExel = new HashMap<String,HashMap<String ,Map<String,Object>>>();
				for (Map<String, Object> map : maps) {
					String id = map.get("id").toString();
					double actualGearsNum = (double) map.get("actualGearsNum");
					double actualRoundNum = (double) map.get("actualRoundNum");
					double reasonNum = (double) map.get("reasonNum");
					String resubmisPerson = map.get("resubmisPerson").toString();
					String arePersons = map.get("arePersons").toString();
					String councilor = (String) map.get("councilor");
					String remark = (String) map.get("remark");
					taskReportFacade.updateExecuteReportByOp(actualGearsNum, actualRoundNum, councilor, remark, resubmisPerson, id, reasonNum, arePersons);
				}
			} else {
				for (Map<String, Object> map : maps) {
					String id = map.get("id").toString();
					double MGGearsNum = (double) map.get("MGGearsNum");
					double MGRoundNum = (double) map.get("MGRoundNum");
					double projectProvideNum = (double) map.get("projectProvideNum");
					double clientProvideNum = (double) map.get("clientProvideNum");
					taskReportFacade.updateExecuteReportByPM(MGGearsNum, MGRoundNum, projectProvideNum,clientProvideNum, id);
				}

			}
			taskReportFacade.updateExecuteReportMgr(demandIdSet,isNeedExecute);
		}
	}

	private  void checkNum(FileOperationResult fileOperationResult, List<Map<String, Object>> maps, Set<String> set,Set<String> demandIdSet, Sheet sheet, String subSchemaCode, boolean isNeedExecute) {
		if("ZPXQZBGL".equals(subSchemaCode)){
			String sheetName = sheet.getSheetName();
			if(!"线上招聘周报-项目组复核".equals(sheetName)){
				fileOperationResult.setErrorType(10);
				fileOperationResult.setErrorMsg("导入的模板有误，请重新导入!");
				return ;
			}
			List<Integer> lines = new ArrayList<>();

			HashMap<String, Set<String>> demandIdMap = new HashMap<>();
			for (int k = 4; k <= sheet.getLastRowNum(); k++) {
				Row row = sheet.getRow(k);
				if (row == null) {
					continue;
				}
				if(row.getLastCellNum() >= 31 && StringUtils.isNotBlank(sheet.getRow(k).getCell(31).getStringCellValue())){
					String demandId  = convertToString(sheet.getRow(k).getCell(1));
					String id  =  convertToString(sheet.getRow(k).getCell(31));
					if(demandIdMap.containsKey(demandId)){
						demandIdMap.get(demandId).add(id);
					}else{
						Set<String> idSet = new HashSet<>();
						idSet.add(id);
						demandIdMap.put(demandId,idSet);
					}
				}
			}
			List<Map<String,Object>> resultListMap = taskReportFacade.getCalculateNum(demandIdMap, "线上");

			HashMap<String, Double> calculateMap = new HashMap<>();
			for (int k = 4; k <= sheet.getLastRowNum(); k++) {
				HashMap<String, Object> map = new HashMap<>();
				Row row = sheet.getRow(k);
				if (row == null) {
					continue;
				}
				if(row.getLastCellNum() >= 31 && StringUtils.isNotBlank(sheet.getRow(k).getCell(31).getStringCellValue())){

					String demandId  = convertToString(sheet.getRow(k).getCell(1));
					String id = convertToString(sheet.getRow(k).getCell(31));
					set.add(id);
					//double demandFor = cellToDouble(sheet.getRow(k).getCell(19));
					double onlineRecruitmentNum = cellToDouble(sheet.getRow(k).getCell(28));
					double projectProvideNum = cellToDouble(sheet.getRow(k).getCell(29));
					map.put("demandId", demandId);
					demandIdSet.add(demandId);
					map.put("onlineRecruitmentNum", onlineRecruitmentNum);

					map.put("projectProvideNum", projectProvideNum);
					map.put("comment", convertToString(sheet.getRow(k).getCell(30)));
					map.put("id", id);
					maps.add(map);
					if(calculateMap.containsKey(demandId)) {
						calculateMap.put(demandId, calculateMap.get(demandId) + onlineRecruitmentNum + projectProvideNum);
					} else {
						calculateMap.put(demandId,onlineRecruitmentNum + projectProvideNum);
					}
				}
			}

			for(int i=0; i < resultListMap.size(); i++) {
				Map tempMap = resultListMap.get(i);
				String demandId = tempMap.get("demandId").toString();
				double demandFor = (Double) tempMap.get("demandFor");
				double existNum = (Double) tempMap.get("existNum");
				double inputNum = calculateMap.get(demandId);
				if(inputNum + existNum > demandFor){
					fileOperationResult.setErrorType(12);
					fileOperationResult.setErrorMsg("上传的数据已经超过总需求数，请修改后重新上传!");
					return;
				}
			}

		}else if("XXZPXQZBGL".equals(subSchemaCode)) {
			if(isNeedExecute) {
				String sheetName = sheet.getSheetName();
				if(!"线下招聘周报-执行填报".equals(sheetName)){
					fileOperationResult.setErrorType(10);
					fileOperationResult.setErrorMsg("导入的模板有误，请重新导入!");
					return ;
				}
				HashMap<String, Set<String>> demandIdMap = new HashMap<>();
				for (int k = 4; k <= sheet.getLastRowNum(); k++) {
					HashMap<String, Object> map = new HashMap<>();
					Row row = sheet.getRow(k);
					if (row == null) {
						continue;
					}
					if (row.getLastCellNum() >= 28 && StringUtils.isNotBlank(sheet.getRow(k).getCell(28).getStringCellValue())) {
						String demandId  = convertToString(sheet.getRow(k).getCell(1));
						String id  =  convertToString(sheet.getRow(k).getCell(28));
						String recruitmentType = convertToString(sheet.getRow(k).getCell(19));
						if(demandIdMap.containsKey(demandId)){
							demandIdMap.get(demandId).add(id);
						}else if(!"不确定人数".equals(recruitmentType)){
							Set<String> idSet = new HashSet<>();
							idSet.add(id);
							demandIdMap.put(demandId,idSet);
						}
					}
				}
				//获取非不确定人数需求的  总需求数和 (完成数+客户推荐数+项目推荐数)
				List<Map<String,Object>> resultListMap = taskReportFacade.getCalculateNum(demandIdMap, "线下");

				HashMap<String, Double> calculateMap = new HashMap<>();
				for (int k = 4; k <= sheet.getLastRowNum(); k++) {
					HashMap<String, Object> map = new HashMap<>();
					Row row = sheet.getRow(k);
					if (row == null) {
						continue;
					}
					if (row.getLastCellNum() >= 28 && StringUtils.isNotBlank(sheet.getRow(k).getCell(28).getStringCellValue())) {
						String demandId =  convertToString(sheet.getRow(k).getCell(1));
						String id = convertToString(sheet.getRow(k).getCell(28));
						set.add(id);
						demandIdSet.add(demandId);
						map.put("demandId", demandId);
						map.put("finishedNum", cellToDouble(sheet.getRow(k).getCell(23)));
						map.put("plannedNum", cellToDouble(sheet.getRow(k).getCell(24)));
						map.put("recommendNum", cellToDouble(sheet.getRow(k).getCell(25)));
						map.put("councilor", convertToString(sheet.getRow(k).getCell(26)));
						map.put("comment", convertToString(sheet.getRow(k).getCell(27)));
						map.put("id", id);
						map.put("resubmisPerson","[{\"id\":\""+getUserId()+"\",\"type\":"+3+"}]");
						String recruitmentType = convertToString(sheet.getRow(k).getCell(19));
						//if ("不确定人数".equals(recruitmentType)) {
						//	map.put("MGFinishedNum", cellToDouble(sheet.getRow(k).getCell(25)));
						//} else {
						//	map.put("MGFinishedNum", cellToDouble(sheet.getRow(k).getCell(23)));
						//}
						maps.add(map);

						if(!"不确定人数".equals(recruitmentType)){
							//按 需求id 累加完成数
							if(calculateMap.containsKey(demandId)) {
								calculateMap.put(demandId, calculateMap.get(demandId) + cellToDouble(sheet.getRow(k).getCell(23)));
							}else{
								calculateMap.put(demandId, cellToDouble(sheet.getRow(k).getCell(23)));
							}
						}else{
							//按 需求id 累加 推荐数
							if(calculateMap.containsKey(demandId)) {
								calculateMap.put(demandId, calculateMap.get(demandId) + cellToDouble(sheet.getRow(k).getCell(25)));
							}else{
								calculateMap.put(demandId, cellToDouble(sheet.getRow(k).getCell(25)));
							}
						}
					}
				}
				for(int i=0; i < resultListMap.size(); i++) {
					Map tempMap = resultListMap.get(i);
					String demandId = tempMap.get("demandId").toString();
					double demandFor = (Double) tempMap.get("demandFor");
					double existNum = (Double) tempMap.get("existNum");
					double inputNum = calculateMap.get(demandId);
					if(inputNum + existNum > demandFor){
						fileOperationResult.setErrorType(12);
						fileOperationResult.setErrorMsg("上传的数据已经超过总需求数，请修改后重新上传!");
						return;
					}
				}
			}else {
				String sheetName = sheet.getSheetName();
				if(!"线下招聘周报-项目组复核".equals(sheetName)){
					fileOperationResult.setErrorType(10);
					fileOperationResult.setErrorMsg("导入的模板有误，请重新导入!");
					return ;
				}
				HashMap<String, Set<String>> demandIdMap = new HashMap<>();
				for (int k = 4; k <= sheet.getLastRowNum(); k++) {
					HashMap<String, Object> map = new HashMap<>();
					Row row = sheet.getRow(k);
					if (row == null) {
						continue;
					}
					if (row.getLastCellNum() >= 31 && StringUtils.isNotBlank(sheet.getRow(k).getCell(31).getStringCellValue())) {
						String demandId  = convertToString(sheet.getRow(k).getCell(1));
						String id  =  convertToString(sheet.getRow(k).getCell(31));
						String recruitmentType = convertToString(sheet.getRow(k).getCell(19));
						if(demandIdMap.containsKey(demandId)){
							demandIdMap.get(demandId).add(id);
						}else if(!"不确定人数".equals(recruitmentType)){
							Set<String> idSet = new HashSet<>();
							idSet.add(id);
							demandIdMap.put(demandId,idSet);
						}
					}
				}
				List<Map<String,Object>> resultListMap = taskReportFacade.getCalculateNum(demandIdMap, "线下");

				HashMap<String, Double> calculateMap = new HashMap<>();
				List<Integer> lines = new ArrayList<>();
				for (int k = 4; k <= sheet.getLastRowNum(); k++) {
					HashMap<String, Object> map = new HashMap<>();
					Row row = sheet.getRow(k);
					if (row == null) {
						continue;
					}
					if(row.getLastCellNum() >= 31 && StringUtils.isNotBlank(sheet.getRow(k).getCell(31).getStringCellValue())){
						String demandId =  convertToString(sheet.getRow(k).getCell(1));
						String id = convertToString(sheet.getRow(k).getCell(31));
						set.add(id);
						double demandFor = cellToDouble(sheet.getRow(k).getCell(20));
						double MGFinishedNum = cellToDouble(sheet.getRow(k).getCell(28));
						double clientProvideNum = cellToDouble(sheet.getRow(k).getCell(29));
						double projectProvideNum = cellToDouble(sheet.getRow(k).getCell(30));
						demandIdSet.add(demandId);
						String recruitmentType = convertToString(sheet.getRow(k).getCell(19));
						map.put("year",convertToString(sheet.getRow(k).getCell(3)));
						map.put("month",convertToString(sheet.getRow(k).getCell(4)));
						map.put("cycle",convertToString(sheet.getRow(k).getCell(22)));
						map.put("demandId", demandId);
						map.put("MGFinishedNum", MGFinishedNum);
						map.put("clientProvideNum", clientProvideNum);
						map.put("projectProvideNum", projectProvideNum);
						map.put("id", id);
						maps.add(map);
						if(MGFinishedNum + clientProvideNum + projectProvideNum > demandFor){
							lines.add(k+1);
						}
						if(calculateMap.containsKey(demandId)) {
							calculateMap.put(demandId, calculateMap.get(demandId) + MGFinishedNum + clientProvideNum + projectProvideNum);
						} else if(!"不确定人数".equals(recruitmentType)){
							calculateMap.put(demandId,MGFinishedNum + clientProvideNum + projectProvideNum);
						}
					}
				}

				for(int i=0; i < resultListMap.size(); i++) {
					Map tempMap = resultListMap.get(i);
					String demandId = tempMap.get("demandId").toString();
					double demandFor = (Double) tempMap.get("demandFor");
					double existNum = (Double) tempMap.get("existNum");
					double inputNum = calculateMap.get(demandId);
					if(inputNum + existNum > demandFor){
						fileOperationResult.setErrorType(12);
						fileOperationResult.setErrorMsg("上传的数据已经超过总需求数，请修改后重新上传!");
						return;
					}
				}

			}
		} else if("ZXZBGL".equals(subSchemaCode)) {
			if(isNeedExecute) {
				String sheetName = sheet.getSheetName();
				if(!"执行周报-执行填报".equals(sheetName)){
					fileOperationResult.setErrorType(10);
					fileOperationResult.setErrorMsg("导入的模板有误，请重新导入!");
					return ;
				}
				List<Integer> lines = new ArrayList<>();
				HashMap<String, Set<String>> calculateMap = new HashMap<>();
				for (int k = 4; k <= sheet.getLastRowNum(); k++) {
					HashMap<String, Object> map = new HashMap<>();
					Row row = sheet.getRow(k);
					if (row == null) {
						continue;
					}
					if (row.getLastCellNum() >= 28 && StringUtils.isNotBlank(sheet.getRow(k).getCell(27).getStringCellValue())) {
						String demandId  = convertToString(sheet.getRow(k).getCell(27));
						String id  =  convertToString(sheet.getRow(k).getCell(26));
						if(calculateMap.containsKey(demandId)){
							calculateMap.get(demandId).add(id);
						}else{
							Set<String> idSet = new HashSet<>();
							idSet.add(id);
							calculateMap.put(demandId,idSet);
						}
					}
				}

				for (int k = 4; k <= sheet.getLastRowNum(); k++) {
					HashMap<String, Object> map = new HashMap<>();
					Row row = sheet.getRow(k);
					if (row == null) {
						continue;
					}
					if (row.getLastCellNum() >= 28 && StringUtils.isNotBlank(sheet.getRow(k).getCell(27).getStringCellValue())) {
						set.add(sheet.getRow(k).getCell(26).getStringCellValue());
						demandIdSet.add(convertToString(sheet.getRow(k).getCell(27)));
						map.put("demandId", convertToString(sheet.getRow(k).getCell(27)));
						map.put("year", convertToString(sheet.getRow(k).getCell(1)));
						map.put("month", convertToString(sheet.getRow(k).getCell(2)));
						map.put("cycle", convertToString(sheet.getRow(k).getCell(16)));
						map.put("storeNum", cellToDouble(sheet.getRow(k).getCell(17)));
						map.put("planGearsNum", cellToDouble(sheet.getRow(k).getCell(18)));
						map.put("planRoundNum", cellToDouble(sheet.getRow(k).getCell(19)));
						map.put("actualGearsNum", cellToDouble(sheet.getRow(k).getCell(20)));
						map.put("actualRoundNum", cellToDouble(sheet.getRow(k).getCell(21)));
						map.put("councilor", convertToString(sheet.getRow(k).getCell(22)));

						String name = convertToString(sheet.getRow(k).getCell(23));
						String userId = atsService.getUserIdByName(name);

						map.put("arePersons", "[{\"id\":\""+userId+"\",\"type\":"+3+"}]");
						map.put("reasonNum", cellToDouble(sheet.getRow(k).getCell(24)));

						map.put("remark", convertToString(sheet.getRow(k).getCell(25)));
						map.put("id", convertToString(sheet.getRow(k).getCell(26)));
						map.put("resubmisPerson","[{\"id\":\""+getUserId()+"\",\"type\":"+3+"}]");
						maps.add(map);
						//if(cellToDouble(sheet.getRow(k).getCell(18)) < cellToDouble(sheet.getRow(k).getCell(20))
						//		|| cellToDouble(sheet.getRow(k).getCell(19)) < cellToDouble(sheet.getRow(k).getCell(21))){
						//	lines.add(k+1);
						//}
					}
				}
				if(lines.size() > 0){
					fileOperationResult.setErrorType(12);
					fileOperationResult.setErrorCount(lines.size());
					fileOperationResult.setErrorMsg("上传文件中存在错误数据，行号为:"+lines.toString() +"，请修改后重新上传!");
					return;
				}
			} else {
				String sheetName = sheet.getSheetName();
				if(!"执行周报-项目组复核".equals(sheetName)){
					fileOperationResult.setErrorType(10);
					fileOperationResult.setErrorMsg("导入的模板有误，请重新导入!");
					return ;
				}
				List<Integer> lines = new ArrayList<>();
				for (int k = 4; k <= sheet.getLastRowNum(); k++) {
					HashMap<String, Object> map = new HashMap<>();
					Row row = sheet.getRow(k);
					if (row == null) {
						continue;
					}
					if(row.getLastCellNum() >= 32 && StringUtils.isNotBlank(sheet.getRow(k).getCell(31).getStringCellValue())){
						set.add(sheet.getRow(k).getCell(30).getStringCellValue());
						demandIdSet.add(convertToString(sheet.getRow(k).getCell(31)));
						map.put("demandId", convertToString(sheet.getRow(k).getCell(31)));
						map.put("year", convertToString(sheet.getRow(k).getCell(1)));
						map.put("month", convertToString(sheet.getRow(k).getCell(2)));
						map.put("cycle", convertToString(sheet.getRow(k).getCell(16)));
						map.put("storeNum", cellToDouble(sheet.getRow(k).getCell(17)));
						map.put("planGearsNum", cellToDouble(sheet.getRow(k).getCell(18)));
						map.put("planRoundNum", cellToDouble(sheet.getRow(k).getCell(19)));
						map.put("actualGearsNum", cellToDouble(sheet.getRow(k).getCell(20)));
						map.put("actualRoundNum", cellToDouble(sheet.getRow(k).getCell(21)));
						map.put("councilor", convertToString(sheet.getRow(k).getCell(22)));

						String name = convertToString(sheet.getRow(k).getCell(23));
						String userId = atsService.getUserIdByName(name);

						map.put("arePersons", "[{\"id\":\""+userId+"\",\"type\":"+3+"}]");
						map.put("reasonNum", cellToDouble(sheet.getRow(k).getCell(24)));

						map.put("remark", convertToString(sheet.getRow(k).getCell(25)));
						map.put("MGGearsNum", cellToDouble(sheet.getRow(k).getCell(26)));
						map.put("MGRoundNum", cellToDouble(sheet.getRow(k).getCell(27)));
						map.put("projectProvideNum", cellToDouble(sheet.getRow(k).getCell(28)));
						map.put("clientProvideNum", cellToDouble(sheet.getRow(k).getCell(29)));
						map.put("id", convertToString(sheet.getRow(k).getCell(30)));
						maps.add(map);
						//if(cellToDouble(sheet.getRow(k).getCell(18)) < cellToDouble(sheet.getRow(k).getCell(26))
						//	|| cellToDouble(sheet.getRow(k).getCell(19)) < cellToDouble(sheet.getRow(k).getCell(27))){
						//	lines.add(k+1);
						//}
					}
				}
				if(lines.size() > 0){
					fileOperationResult.setErrorType(12);
					fileOperationResult.setErrorCount(lines.size());
					fileOperationResult.setErrorMsg("上传文件中存在错误数据，行号为:"+lines.toString() +"，请修改后重新上传!");
					return;
				}
			}
		}else if("ZXXQTB".equals(subSchemaCode)) {
			String sheetName = sheet.getSheetName();
			if(!"门店信息导入".equals(sheetName)){
				fileOperationResult.setErrorType(10);
				fileOperationResult.setErrorMsg("导入的模板有误，请重新导入!");
				return ;
			}
			List<Integer> lines = new ArrayList<>();
			String executeDemand  = convertToString(sheet.getRow(4).getCell(1));
			String subjectName  = null;
			if(StringUtils.isNotBlank(executeDemand)){
				//根据id获取招聘需求提报的相关信息
				BizObjectQueryModel queryModel = new BizObjectQueryModel();
				PageableImpl pageable = new PageableImpl(0, 9999);
				queryModel.setSchemaCode("ZXXQTB");
				queryModel.setQueryCode("ZXXQTB");
				queryModel.setPageable(pageable);
				FilterExpression filterExpression = Q.it("id", FilterExpression.Op.Eq, executeDemand);
				queryModel.setFilterExpr(filterExpression);
				BizObjectQueryModel.Options option = new BizObjectQueryModel.Options();
				option.setQueryDisplayType(QueryDisplayType.APPEND);
				option.setCustomDisplayColumns(Arrays.asList("id","creater","createdDeptId","demandCreatedTime", "activityStartTime","activityEndTime",
						"operator","postJD","executeDetails","projectName","recruitmentType","frontOperator","operator","activityName", "projectNameStr",
						"industry","qthysm","projectNameStr","jobNature","projectNo"));
				queryModel.setOptions(option);
				Page<BizObjectModel> pages = getBizObjectFacade().queryBizObjects(queryModel);
				subjectName = ((HashMap<String,Object>)getBizObjectFacade().queryBizObjects(queryModel).getContent().get(0).getData().get("projectName")).get("id").toString();
			}
			for (int k = 4; k <= sheet.getLastRowNum(); k++) {
				HashMap<String, Object> map = new HashMap<>();
				Row row = sheet.getRow(k);
				if (row == null) {
					continue;
				}
				map.put("demandId", convertToString(sheet.getRow(k).getCell(1)));
				map.put("executeDemand", convertToString(sheet.getRow(k).getCell(1)));
				map.put("projectNo", convertToString(sheet.getRow(k).getCell(2)));
				// TODO 这里需要查出项目需求的id
				map.put("subjectName", subjectName);
				map.put("activityName", convertToString(sheet.getRow(k).getCell(4)));
				map.put("customerStoreNum", convertToString(sheet.getRow(k).getCell(5)));
				map.put("province", convertToString(sheet.getRow(k).getCell(6)));
				map.put("cityName", convertToString(sheet.getRow(k).getCell(7)));
				map.put("district", convertToString(sheet.getRow(k).getCell(8)));
				map.put("storeShortName", convertToString(sheet.getRow(k).getCell(9)));
				map.put("detailArea", convertToString(sheet.getRow(k).getCell(10)));
				map.put("area", convertToString(sheet.getRow(k).getCell(11)));
				map.put("cityLevel", convertToString(sheet.getRow(k).getCell(12)));
				map.put("customDockingPerson", convertToString(sheet.getRow(k).getCell(13)));
				map.put("customLinkType", convertToString(sheet.getRow(k).getCell(14)));
				map.put("storeOutlet", convertToString(sheet.getRow(k).getCell(15)));
				map.put("storeStatus", convertToString(sheet.getRow(k).getCell(16)));
				map.put("id", convertToString(sheet.getRow(k).getCell(17)));
				maps.add(map);
				String key  = convertToString(sheet.getRow(k).getCell(5)) + convertToString(sheet.getRow(k).getCell(6))
						+ convertToString(sheet.getRow(k).getCell(7)) +  convertToString(sheet.getRow(k).getCell(9));
				if(set.contains(key)){
					lines.add(k+1);
				}else {
					set.add(key);
				}
			}
			if(lines.size() > 0){
				fileOperationResult.setErrorType(12);
				fileOperationResult.setErrorCount(lines.size());
				fileOperationResult.setErrorMsg("上传文件中存在错误数据，行号为:"+lines.toString() +"，请修改后重新上传!");
				return;
			}
		}
		fileOperationResult.setErrorType(0);
		fileOperationResult.setErrorMsg("导入成功！");
		return;
	}

	//ZXXQTB

	private double cellToDouble(Cell cell) {
		if(cell == null){
			return  0;
		}
		if ("STRING".equals(cell.getCellType().name())) {
			return Double.parseDouble(cell.getStringCellValue());
		} else if ("NUMERIC".equals(cell.getCellType().name())) {
			return cell.getNumericCellValue();
		}
		return  0;
	}

	private int cellToInt(Cell cell) {
		if(cell == null){
			return  0;
		}
		if ("STRING".equals(cell.getCellType().name())) {
			return Integer.parseInt(cell.getStringCellValue());
		} else if ("NUMERIC".equals(cell.getCellType().name())) {
			return (int)cell.getNumericCellValue();
		}
		return  0;
	}


	@Async
	public FileOperationResult customizedCmportDatas(String userId, String fileName, String schemaCode, String queryCode, String queryField) {
		log.debug("开始执行导入任务");

		FileOperationResult fileOperationResult = new FileOperationResult();
		try {
			fileOperationResult = customizedImportDatas(userId, fileName, schemaCode, queryCode, queryField);
		} catch (Exception e) {
			log.error("data import error.", e);

			fileOperationResult = new FileOperationResult();
			fileOperationResult.setOperationResult(true);
			fileOperationResult.setErrorType(5);
			fileOperationResult.setErrorCount(0);
			fileOperationResult.setSuccessCount(0);

			log.debug("用户id={}：", userId);
			synchronized (mapFileOperateInfo) {
				fileOperationResult = idWorker.refrenceMap(userId, fileOperationResult);
			}
			return fileOperationResult;
		}
		return fileOperationResult;
	}

	/**
	* 批量导入列表数据
	*
	* @param fileName   文件名称
	* @param schemaCode 业务模型编码
	* @param queryCode  查询编码
	* @return FileOperationResult
	*/
	private FileOperationResult customizedImportDatas(String userId, String fileName, String schemaCode, String queryCode, String queryField) {
		mapFileOperateInfo.remove(userId);

		log.debug("开始解析文件");
		FileOperationResult result = new FileOperationResult();
		//原有获取文件格式逻辑在文件名带有点号(例如2.3.xls)时校验错误
		String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1);
		boolean equals = Objects.equals("xlsx", fileExtension);
		boolean equals1 = Objects.equals("xls", fileExtension);
		if (!(equals || equals1)) {
			result.setErrorType(2);
			result.setOperationResult(true);

			mapFileOperateInfo.put(userId, result);
			return result;
		}

		BizSchemaModel bizSchemaModel = getAppManagementFacade().getBizSchemaBySchemaCode(schemaCode, true);

		//固定表头加载顺序，先加载非子表数据项->无内容的子表数据项->有内容的子表数据项
		List<BizQueryColumnModel> oldColumns = getColumns(bizSchemaModel);

		List<BizPropertyModel> propertyList = bizSchemaModel.getProperties();

		List<BizQueryColumnModel> oldHeaderColumns = getHeaderColumns(oldColumns);

		List<BizPropertyType> propertyTypes = oldColumns.stream().map(BizQueryColumnModel::getPropertyType).collect(Collectors.toList());
		List<BizQueryColumnModel> columns = new ArrayList<>();
		List<BizQueryColumnModel> headerColumns = new ArrayList<>();
		//删除三列name数据标题sequenceNo单据号owner拥有者
		List<String> delete = new ArrayList();
		delete.add("name");
		delete.add("owner");
		delete.add("sequenceNo");
		for (BizQueryColumnModel column : oldColumns) {
			if(!column.getSchemaCode().equals(schemaCode)){
				columns.add(column);
				continue;
			}
			if(!delete.contains(column.getPropertyCode())){
				columns.add(column);
			}
		}
		for (BizQueryColumnModel headerColumn : oldHeaderColumns) {
			if(!headerColumn.getSchemaCode().equals(schemaCode)){
				headerColumns.add(headerColumn);
				continue;
			}
			if(!delete.contains(headerColumn.getPropertyCode())){
				headerColumns.add(headerColumn);
			}
		}
		//获取配置的数据项信息
		List<String> propertyCode = columns.stream().map(BizQueryColumnModel::getPropertyCode).collect(Collectors.toList());

		List<Map<String, Object>> dataMaps = FileOperateHelper.getMainImportDatas(fileName, headerColumns, propertyCode);
		if (CollectionUtils.isEmpty(dataMaps) || dataMaps.size() < 1) {
			result.setOperationResult(true);
			result.setSuccessCount(0);
			result.setErrorCount(0);
			result.setErrorType(7);
			mapFileOperateInfo.put(userId, result);
			return result;
		}

		if (dataMaps.size() == 1 && dataMaps.get(0).get("success") != null && dataMaps.get(0).get("success").equals(false)) {
			result.setOperationResult(true);
			result.setErrorType(Integer.valueOf(dataMaps.get(0).get("type").toString()));
			Map<String, Object> objectMap = dataMaps.get(0);
			Integer integer = Objects.isNull(objectMap.get("importSize")) ? Integer.valueOf("500") : Integer.valueOf(objectMap.get("importSize").toString());
			result.setImportSize(integer);
			mapFileOperateInfo.put(userId, result);
			return result;
		}
		log.info("导入数据条数：size={}", dataMaps.size());
		//获取数据
		List<String> headers = headerColumns.stream().map(BizQueryColumnModel::getName).collect(Collectors.toList());
		result = customizedDisposeData(userId, schemaCode, dataMaps, propertyTypes, headers, propertyList, null, queryField, headerColumns, queryCode);
		return result;
	}

	/**
	 * 解析获取到的excel数据
	 *
	 * @param schemaCode    模型编码
	 * @param dataMaps      excel解析后的数据有序
	 * @param propertyTypes 需要展示的数据项类型集合有序
	 * @param headers       表头集合有序
	 * @param properties    模型对应的数据项有序
	 * @return FileOperationResult
	 */
	private FileOperationResult customizedDisposeData(String userId, String schemaCode, List<Map<String, Object>> dataMaps, List<BizPropertyType> propertyTypes, List<String> headers, List<BizPropertyModel> properties, Map<String, List<String>> attrituteMaps, String queryField, List<BizQueryColumnModel> headerColumns, String queryCode) {
		mapFileOperateInfo.remove(userId);
		//错误信息
		List<Map<String, Object>> errorMaps = new ArrayList<>();
		//导入数据
		List<BizObjectModel> bizObjects = new ArrayList<>();

		//子表数据
		List<Map<String, Object>> childMaps = new ArrayList<>();

		//二次重试
		List<Map<String, Object>> secondList = Lists.newArrayList();

		List<String> editCodes = null;
		if (attrituteMaps != null) {
			editCodes = attrituteMaps.get("editCodes");
			if (CollectionUtils.isEmpty(editCodes)) {
				//防止没有可写项
				editCodes.add("id");
			}
		}
		//主表
		boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}

		//传参参数过多问题
		Map<String, Object> paramMap = Maps.newHashMap();
		paramMap.put("userId", userId);
		paramMap.put("bizObjects", bizObjects);
		paramMap.put("editCodes", editCodes);
		paramMap.put("schemaCode", schemaCode);
		paramMap.put("propertyTypes", propertyTypes);
		paramMap.put("headers", headers);
		paramMap.put("queryField", queryField);
		paramMap.put("headerColumns", headerColumns);

		FileOperationResult operationResult = new FileOperationResult();
		operationResult.setDropdownMarkedCount(0);
		operationResult.setRadioMarkedCount(0);
		operationResult.setCheckboxMarkedCount(0);
		//校验
		checkDataItems(errorMaps, childMaps, dataMaps, properties, attrituteMaps, paramMap, secondList, queryCode, operationResult);
		int errorType = 0;
		boolean empty = CollectionUtils.isEmpty(secondList);
		boolean empty1 = CollectionUtils.isEmpty(errorMaps);
		boolean empty2 = CollectionUtils.isEmpty(bizObjects);
		boolean equals = (!empty1) && (empty2);
		boolean equals1 = (!empty1) && (!empty2);
		boolean equals2 = (empty) && (empty1) && (!empty2);
		boolean equals3 = !empty && empty1;
		if (equals3) {
			log.info("重试数据条数：retrySize={}", secondList.size());
			errorType = 8;
		} else if (equals) {
			log.info("失败数据条数：errorSize={}", errorMaps.size());
			errorType = 1;
		} else if (equals1) {
			log.info("数据条数：errorSize={},successSize={}", errorMaps.size(), bizObjects.size());
			errorType = 1;
		} else if (equals2) {
			log.info("成功数据条数：successSize={}", bizObjects.size());
			errorType = 0;
		}
		List<Map<String, Object>> list = CollectionUtils.isEmpty(secondList) ? new ArrayList<>() : secondList;
		operationResult.setSecondImportData(list);
		operationResult.setErrorType(errorType);
		operationResult.setSuccessCount(0);
		operationResult.setErrorCount(0);
		operationResult.setOperationResult(true);
		//批量更新
		if (CollectionUtils.isNotEmpty(errorMaps) && errorMaps.size() > 0) {
			//创建错误信息excel
			if (CollectionUtils.isNotEmpty(headers)) {
				headers.add("错误信息");
			}
			Boolean isChild = !isQueryData;
			String fileName = FileOperateHelper.createFiles(headers, errorMaps, isChild, headerColumns);
			operationResult.setErrorCount(errorMaps.size());
			operationResult.setFileName(fileName);
		}
		if (CollectionUtils.isNotEmpty(secondList)) {
			operationResult.setRetryCount(secondList.size());
			operationResult.setHeadColumns(headerColumns);
			operationResult.setSecondImportData(secondList);
			if (StringUtils.isNotEmpty(queryField)) {
				operationResult.setQueryField(queryField);
			}
		}
		if (isQueryData) {
			mapFileOperateInfo.put(userId, operationResult);
		}
		if (CollectionUtils.isNotEmpty(bizObjects)) {
			operationResult.setSuccessCount(bizObjects.size());
			getBizObjectFacade().addBizObjects(userId, bizObjects, queryField);
			log.info("==================批量更新========成功导入={}条", bizObjects.size());
		}
		if (CollectionUtils.isNotEmpty(childMaps)) {
			operationResult.setData(childMaps);
			operationResult.setSuccessCount(childMaps.size());
		}

		return operationResult;
	}

	//遍历excel表格传过来的值，校验对应数据项格式是否正确
	private void checkDataItems(List<Map<String, Object>> errorMaps, List<Map<String, Object>> childMaps,
								List<Map<String, Object>> dataMaps, List<BizPropertyModel> properties,
								Map<String, List<String>> attrituteMaps, Map<String, Object> paramMap,
								List<Map<String, Object>> secondList, String queryCode, FileOperationResult operationResult) {

		//取出map中的参数
		String userId = String.valueOf(paramMap.get("userId"));
		List<BizObjectModel> bizObjects = (List<BizObjectModel>) paramMap.get("bizObjects");
		List<String> editCodes = (List<String>) paramMap.get("editCodes");
		String schemaCode = String.valueOf(paramMap.get("schemaCode"));
		List<BizPropertyType> propertyTypes = (List<BizPropertyType>) paramMap.get("propertyTypes");
		List<String> headers = (List<String>) paramMap.get("headers");
		String queryField = String.valueOf(paramMap.get("queryField"));
		List<BizQueryColumnModel> headerColumns = (List<BizQueryColumnModel>) paramMap.get("headerColumns");
		UserModel user = getOrganizationFacade().getUser(userId);
		String corpId = user.getCorpId();
		Boolean isBind = false;
		Map<String, List<BizPropertyModel>> childMap = Maps.newHashMap();
		//内存中预先存储子表及其数据项信息
		if (CollectionUtils.isNotEmpty(headerColumns)) {
			List<String> childProperties = headerColumns.stream().filter(bizQueryColumnModel -> Objects.equals(bizQueryColumnModel.getPropertyType(), BizPropertyType.CHILD_TABLE)).map(BizQueryColumnModel::getPropertyCode).collect(Collectors.toList());
			if (CollectionUtils.isNotEmpty(childProperties)) {
				for (String code : childProperties) {
					BizSchemaModel bizSchemaBySchemaCode = getAppManagementFacade().getBizSchemaBySchemaCode(code);
					List<BizPropertyModel> childPropertyList = bizSchemaBySchemaCode.getProperties();
					childMap.put(code, childPropertyList);
				}
			}
		}
		BizFormModel bizFormModel = getBizFormModel(schemaCode, queryCode);

		String formCode = getAppManagementFacade().getBizForms(schemaCode).get(0).getCode();
		Map<String, Object> multWorkMap = initMultWorkSheet(properties, schemaCode, queryCode);
		List<String> defaultCodes = Arrays.stream(DefaultPropertyType.values()).map(DefaultPropertyType::getCode).collect(Collectors.toList());

		Map<String, String> textInfos = null;
		Map<String, String> radioInfos = null;
		Map<String, String> checkboxInfos = null;
		Map<String, String> dropdownInfos = null;
		Map<String, Map<String, String>> dropdownInfos2 = null;
		if (attrituteMaps != null) {
			editCodes = attrituteMaps.get("editCodes");
			if (CollectionUtils.isEmpty(editCodes)) {
				//防止没有可写项
				editCodes.add("id");
			}
			textInfos = parseAttribute(attrituteMaps, "Text");
			radioInfos = parseAttribute(attrituteMaps, "Radio");
			checkboxInfos = parseAttribute(attrituteMaps, "Checkbox");
			dropdownInfos = parseAttribute(attrituteMaps, "Dropdown");

			dropdownInfos2 = parseAttribute_dropdown(attrituteMaps, "Dropdown");
		}
		//主表
		boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		DepartmentModel rootDept = getOrganizationFacade().getRootDepartmentByCorpId(corpId);
		RelatedCorpSettingModel relatedSettingModel = getSystemManagementFacade().getRelatedCorpSettingModelByCorpId(corpId);
		//组织机构是关联/主组织
		OrgType orgType = relatedSettingModel.getOrgType();

		//遍历
		for (Map<String, Object> map : dataMaps) {
			if (MapUtils.isEmpty(map)) {
				continue;
			}
			BizObjectModel bizObject = new BizObjectModel(schemaCode, null, false);

			boolean success = true;

			boolean ok = true;

			//错误的数据集合
			Map<String, Object> mapTemplates = new LinkedHashMap<>();

			//错误数据列
			List<ErrorValue> list = Lists.newLinkedList();

			Map<String, Object> workSheet = Maps.newLinkedHashMap();
			Map<String, Object> multWorkSheet = Maps.newLinkedHashMap();

			List<Object> errList = Lists.newArrayList();

			//先将每个列表对象的主表数据存入；
			if (CollectionUtils.isNotEmpty(headerColumns)) {
				List<String> collect = headerColumns.stream().filter(headerColumn -> (!Objects.equals(headerColumn.getPropertyType(), BizPropertyType.CHILD_TABLE))).map(BizQueryColumnModel::getPropertyCode).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(collect)) {
					for (String code : collect) {
						mapTemplates.put(code, map.get(code));
					}
				}
			} else {
				mapTemplates.putAll(map);
			}
			int i = 0;
			for (String key : map.keySet()) {
				String value = map.get(key) == null ? "" : String.valueOf(map.get(key));
				BizPropertyModel bizProperty = properties.stream().filter(t -> t.getCode().equals(key)).findAny().orElse(null);
				Boolean notEmpty = bizProperty.getPropertyEmpty();
				if (Objects.isNull(notEmpty)) {
					notEmpty = true;
				}

				BizPropertyType bizPropertyType = bizProperty.getPropertyType();
				Object childValue = map.get(key);
				//todo: 数据项校验格式：
				//传参Map
				Map<String, Object> params = Maps.newHashMap();
				params.put("i", i);
				params.put("propertyTypes", propertyTypes);
				params.put("notEmpty", notEmpty);
				params.put("editCodes", editCodes);
				params.put("list", list);
				params.put("bizProperty", bizProperty);
				params.put("value", value);
				params.put("headers", headers);
				params.put("key", key);
				params.put("defaultCodes", defaultCodes);
				params.put("textInfos", textInfos);
				params.put("radioInfos", radioInfos);
				params.put("checkboxInfos", checkboxInfos);
				params.put("dropdownInfos", dropdownInfos);
				params.put("childValue", childValue);
				params.put("multWorkMap", multWorkMap);
				params.put("multWorkSheet", multWorkMap);

				switch (bizPropertyType) {
					case WORK_SHEET:
						checkWorkSheet(params, map, workSheet);
						break;

					case MULT_WORK_SHEET:
						checkMultWorkSheet(params, map, multWorkSheet);
						break;

					case NUMERICAL:
						checkNumerical(params, map);
						break;

					case DATE:
						checkDate(params, map);
						break;

					case LOGICAL:
						checkLogical(params, map);
						break;

					case LONG_TEXT:
						checkLongText(params, map, textInfos);
						break;

					case SHORT_TEXT:
						checkShortText(defaultCodes, textInfos, radioInfos, checkboxInfos, dropdownInfos,
								params, map, operationResult, dropdownInfos2, bizFormModel);
						break;

					case SELECTION:
						success = checkSelection(defaultCodes, params, map, success, corpId, userId, rootDept, orgType);
						break;

					case CHILD_TABLE:
						ok = checkChild(params, map, key, mapTemplates, errList, ok,
								childMap, corpId, rootDept, orgType, bizFormModel);
						break;

					default:
				}

				//todo:
				if (!isQueryData && !editCodes.contains(bizProperty.getCode())) {
					map.put(bizProperty.getCode(), null);
					i++;
					continue;
				}
				i++;
			}

			if (isQueryData && StringUtils.isNotEmpty(queryField)) {
				//检验是否已关联流程实例
				isBind = getBizObjectFacade().checkBindWorkFlowInstance(userId, bizObject, queryField);
				if (log.isDebugEnabled()) {
					log.debug("检验是否已关联流程实例66,bizObject={},queryField={},isBind={},isQueryData={}", JSONObject.toJSONString(bizObject), queryField, isBind, isQueryData);
				}
				if (isBind) {
					ErrorValue errorValue15 = new ErrorValue();
					errorValue15.setContent("表单已关联流程实例，不允许导入");
					list.add(errorValue15);
				}
			}
			errList.addAll(list);
			if (CollectionUtils.isEmpty(errList) && (errList.size() < 1)) {
				if (ok && success) {
					Object owner = map.get("owner");
					if (Objects.nonNull(owner)) {
						List<SelectionValue> owner1 = (List<SelectionValue>) owner;
						SelectionValue selectionValue = owner1.get(0);
						if (selectionValue != null && StringUtils.isNotEmpty(selectionValue.getId())) {
							String id = selectionValue.getId();
							map.put("owner", id);
						}
					}
					//正常数据的子表的关联表单数据项处理
					List<BizPropertyModel> child = properties.stream().filter(property -> Objects.equals(property.getPropertyType(), BizPropertyType.CHILD_TABLE)).collect(Collectors.toList());
					if (CollectionUtils.isNotEmpty(child)) {
						for (BizPropertyModel bizPropertyModel : child) {
							BizSchemaModel subSchema = bizPropertyModel.getSubSchema();
							List<BizPropertyModel> subProperties = subSchema.getProperties();
							if (CollectionUtils.isEmpty(subProperties)) {
								continue;
							}
							List<String> codes = subProperties.stream().filter(subProperty -> Objects.equals(subProperty.getPropertyType(), BizPropertyType.WORK_SHEET)).map(BizPropertyModel::getCode).collect(Collectors.toList());
							if (CollectionUtils.isEmpty(codes)) {
								continue;
							}
							String code = bizPropertyModel.getCode();
							List<Map<String, Object>> subMap = (List<Map<String, Object>>) map.get(code);
							if (CollectionUtils.isEmpty(subMap)) {
								continue;
							}
							for (Map<String, Object> sub : subMap) {
								if (MapUtils.isEmpty(sub)) {
									continue;
								}
								codes.forEach(subCode -> sub.put(subCode, Objects.isNull(sub.get(subCode)) ? null : ((BizObjectModel) sub.get(subCode)).getId()));
							}

						}
					}
					bizObject = new BizObjectModel(schemaCode, map, false);
				} else {
					//需要二次导入的数据的关联表单数据处理
					if (MapUtils.isNotEmpty(workSheet)) {
						workSheet.keySet().forEach(key -> map.put(key, workSheet.get(key)));
					}
					secondList.add(map);
				}
			}

			if (CollectionUtils.isEmpty(errList) && (errList.size() < 1) && ok && success) {
				if (isQueryData && !isBind) {
					bizObject.setStatus(BizObjectStatusType.NEW);
					bizObject.setFormCode(formCode);
					if (bizObject.get(DefaultPropertyType.SEQUENCE_STATUS.getCode()) == null) {
						bizObject.setSequenceStatus(WorkflowInstanceStatus.COMPLETED.name());
					}
					bizObjects.add(bizObject);
				} else {
					childMaps.add(map);
				}
			} else {
				List<String> content = list.stream().map(ErrorValue::getContent).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(errList) && errList.size() > 0) {
					mapTemplates.put("errInfo", content);
					errorMaps.add(mapTemplates);
				}
			}
		}
	}

	//导入的数值格式校验
	private void checkNumerical(Map<String, Object> params, Map<String, Object> map) {
		//参数拿出来
		int i = (int) params.get("i");
		boolean notEmpty = (boolean) params.get("notEmpty");
		List<String> editCodes = (List<String>) params.get("editCodes");
		List<ErrorValue> list = (List<ErrorValue>) params.get("list");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = String.valueOf(params.get("value"));
		String key = String.valueOf(params.get("key"));
		params.get("defaultCodes");
		params.get("textInfos");
		params.get("radioInfos");
		params.get("checkboxInfos");
		params.get("dropdownInfos");
		String name = bizProperty.getName();


		//主表
		boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		if (!isQueryData && !editCodes.contains(bizProperty.getCode())) {
			map.put(bizProperty.getCode(), null);
			i++;
			return;
		}
		if (notEmpty && StringUtils.isEmpty(value)) {
			ErrorValue errorValue15 = new ErrorValue();
			errorValue15.setContent(name + "：该项仅支持数值填写" + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue15);
			i++;
			return;
		}
		if (StringUtils.isNotEmpty(value)) {
			if (PropertyValidateHelper.validateNumberOverMaxLength(value)) {
				ErrorValue errorValue3 = new ErrorValue();
				errorValue3.setContent("【" + name + "】超过限制，最大长度16位，精度8位（8位小数）；");
				list.add(errorValue3);
				i++;
				return;
			}
			if (!PropertyValidateHelper.validateNumerical(value, notEmpty)) {
				ErrorValue errorValue3 = new ErrorValue();
				errorValue3.setContent("【" + name + "】输入格式不对，仅支持整数、1位小数、2位小数、3位小数、4位小数、5位小数、6位小数、7位小数和8位小数共9种数值格式；");
				list.add(errorValue3);
				i++;
				return;
			}
		}
		map.put(bizProperty.getCode(), map.get(key) == null ? null : map.get(key));
		i++;
	}

	//关联表单多选预处理
	private Map<String, Object> initMultWorkSheet(List<BizPropertyModel> properties, String schemaCode, String queryCode) {
        BizFormModel bizFormModel = getBizFormModel(schemaCode, queryCode);
		String publicJsonStr = bizFormModel.getPublishedAttributesJson();
		JSONObject publicJson = JSONObject.parseObject(publicJsonStr);
		Map<String, Object> multWorkMap = Maps.newHashMap();
		List<BizPropertyModel> multWorkProperties = properties.stream().filter(property -> property.getPropertyType() == BizPropertyType.MULT_WORK_SHEET).collect(Collectors.toList());
		multWorkProperties.stream().forEach(mult -> {
			if (Objects.nonNull(publicJson.getJSONObject(mult.getCode()))) {
				JSONObject options = publicJson.getJSONObject(mult.getCode()).getJSONObject("options");
				//取映射字段
				String mappings = options.getString("mappings");

				String mappingKeys = "";
				if (StringUtils.isNotEmpty(mappings)) {
					String[] mappingStrs = mappings.split(";");
					for (int mappingIndex = 0; mappingIndex < mappingStrs.length; mappingIndex++) {
						String mappingKey = mappingStrs[mappingIndex].split(":")[0];
						mappingKeys = mappingKeys + mappingKey + ";";
						String mappingValue = mappingStrs[mappingIndex].split(":")[1];
						if (mappingValue.startsWith("{") && mappingValue.endsWith("}")) {
							mappingValue = mappingValue.replace("{", "").replace("}", "");
							//组装映射关系map
							multWorkMap.put(mult.getCode() + "_" + mappingKey, mappingValue);
						}
						//取映射关系两个子表一样的字段集合
						List<String> sameBizProperties = getTwoChildSameCodeList(mappingKey, mappingValue);
						//保存映射关系一样的字段结合
						multWorkMap.put(mult.getCode() + "_" + mappingKey + "_list", sameBizProperties);
					}
					//保存映射关系目标模型的key集合
					multWorkMap.put(mult.getCode() + "_mappingKeys", mappingKeys.substring(0, mappingKeys.length() - 1));
				}

			}

		});
		return multWorkMap;
	}

	private List<String> getTwoChildSameCodeList(String mappingKey, String mappingValue) {
		BizSchemaModel firstMultChild = getAppManagementFacade().getBizSchemaBySchemaCode(mappingKey, true);
		BizSchemaModel secondMultChild = getAppManagementFacade().getBizSchemaBySchemaCode(mappingValue, true);
		List<BizPropertyModel> firstMutlChildProperties = firstMultChild.getProperties();
		List<BizPropertyModel> secondMutlChildProperties = secondMultChild.getProperties();
		return firstMutlChildProperties.stream().filter(firstMutlChildProperty -> secondMutlChildProperties.stream()
				.anyMatch(secondMutlChildProperty -> firstMutlChildProperty.getCode().equals(secondMutlChildProperty.getCode()) && firstMutlChildProperty.getPropertyType() == secondMutlChildProperty.getPropertyType()) && firstMutlChildProperty.getDefaultProperty() != Boolean.TRUE)
				.collect(Collectors.toList())
				.stream().map(BizPropertyModel::getCode).collect(Collectors.toList());
	}

	//子表格式校验
	private boolean checkChild(Map<String, Object> params, Map<String, Object> map, String code, Map<String, Object> mapTemplate,
							   List<Object> errList, boolean ok, Map<String, List<BizPropertyModel>> childPropertyMaps,
							   String corpId, DepartmentModel rootDept, OrgType orgType, BizFormModel bizFormModel) {

		//错误的map集合
		Map<String, Object> childErrorMap = Maps.newLinkedHashMap();
		boolean success = true;
		BizPropertyModel bizProperty1 = (BizPropertyModel) params.get("bizProperty");
		int i = (int) params.get("i");
		Object errorList = params.get("list");
		List<ErrorValue> list = (List<ErrorValue>) errorList;
		Object notEmpty1 = params.get("notEmpty");
		boolean notEmpty11 = (boolean) notEmpty1;
		String childName = bizProperty1.getName();

		Object childValues = map.get(code);
		if (Objects.isNull(childValues)) {
			if (notEmpty11) {
				ErrorValue errorValue20 = new ErrorValue();
				errorValue20.setContent(childName + (notEmpty11 ? ",不能为空!" : ",可以为空!"));
				list.add(errorValue20);
				i++;
				return success;
			}
			map.put(code, Lists.newArrayList());
		}
		List<Map<String, Object>> childList = Lists.newArrayList();

		List<Map<String, Object>> childs = (List<Map<String, Object>>) childValues;
		List<BizPropertyModel> properties = childPropertyMaps.get(code);

		//错误数据集合
		List<Map<String, Object>> childErrors = Lists.newArrayList();
		if (CollectionUtils.isNotEmpty(childs)) {

			for (Map<String, Object> child : childs) {
				List<ErrorValue> errorLists = Lists.newArrayList();
				Map<String, Object> childMapTemplate = Maps.newLinkedHashMap();
				if (MapUtils.isEmpty(child)) {
					continue;
				}
				List<String> codes = properties.stream().map(BizPropertyModel::getCode).collect(Collectors.toList());
				for (String propertyCode : codes) {
					childMapTemplate.put(propertyCode, child.get(propertyCode));
				}
				Map<String, Object> childMap = Maps.newHashMap();
				for (String key : child.keySet()) {
					List<BizPropertyModel> bizPropertys = properties.stream().filter(propertyModel -> Objects.equals(propertyModel.getCode(), key)).collect(Collectors.toList());
					BizPropertyModel bizProperty = bizPropertys.get(0);
					Boolean notEmpty = bizProperty.getPropertyEmpty();
					String name = bizProperty.getName();
					BizPropertyType propertyType = bizProperty.getPropertyType();
					List<String> defaultCodes = Arrays.stream(DefaultPropertyType.values()).map(DefaultPropertyType::getCode).collect(Collectors.toList());
					Object value = child.get(key);
					switch (propertyType) {

						case WORK_SHEET:
							checkChildWorkSheet(childMap, value, notEmpty, name, errorLists, bizProperty, childName);
							break;
						case MULT_WORK_SHEET:
							checkChildMultWorkSheet(childMap, value, notEmpty, name, errorLists, bizProperty, childName);
							break;

						case NUMERICAL:
							checkChildNumerical(childMap, value, notEmpty, name, errorLists, bizProperty, childName);
							break;

						case DATE:
							checkChildDate(childMap, value, notEmpty, name, errorLists, bizProperty, childName);
							break;

						case LOGICAL:
							checkChildLogical(childMap, value, notEmpty, name, errorLists, bizProperty, childName);
							break;

						case LONG_TEXT:
							checkChildLongText(childMap, value, notEmpty, name, errorLists, bizProperty, childName);
							break;

						case SHORT_TEXT:
							checkChildShortText(defaultCodes, childMap, value, notEmpty, name,
									errorLists, bizProperty, childName, bizFormModel, code);
							break;

						case SELECTION:
							ok = checkChildSelection(childMap, value, notEmpty, bizProperty, ok, corpId, rootDept, orgType);
							break;

						default:
							break;
					}

				}

				List<String> content = errorLists.stream().map(ErrorValue::getContent).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(content)) {
					log.debug("每行字表的错误信息: --{}", content);
				}
				errList.addAll(content);
				childMapTemplate.put("errInfo", content);
				childErrors.add(childMapTemplate);
				childList.add(childMap);
			}
		}
		childErrorMap.put(code, childErrors);
		mapTemplate.putAll(childErrorMap);
		map.put(code, childList);
		i++;
		return ok;
	}

	//子表关联表单格式校验
	private void checkChildWorkSheet(Map<String, Object> map, Object value, Boolean notEmpty, String name, List<ErrorValue> list, BizPropertyModel bizProperty, String childName) {
		if (notEmpty && Objects.isNull(value)) {
			ErrorValue errorValue1 = new ErrorValue();
			errorValue1.setContent(childName + "-" + name + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue1);
			return;
		}

		String value1 = Objects.isNull(value) ? "" : value.toString();

		if (StringUtils.isNotEmpty(value1)) {
			FilterExpression filterExpression = Q.it("name", FilterExpression.Op.Eq, value);
			BizObjectQueryModel bizObjectQueryObject = new BizObjectQueryModel();
			PageableImpl pageable = new PageableImpl(0, Integer.MAX_VALUE);
			String s = ReflectionToStringBuilder.toString(bizProperty, ToStringStyle.SHORT_PREFIX_STYLE);
			log.info("bizProperty关联表单的数据：schemaCode={}", JSONObject.toJSONString(bizProperty.getRelativeCode()));
			bizObjectQueryObject.setSchemaCode(bizProperty.getRelativeCode());
			bizObjectQueryObject.setFilterExpr(filterExpression);
			bizObjectQueryObject.setPageable(pageable);
			BizQueryModel bizQuery = getBizQuery(bizProperty.getRelativeCode(), null, ClientType.PC);
			bizObjectQueryObject.setQueryCode(bizQuery.getCode());
			log.info("关联的code：--{}", bizQuery.getCode());
			bizObjectQueryObject.setClientType(ClientType.PC);
			Page<BizObjectModel> dataTempalte = getBizObjectFacade().queryBizObjects(bizObjectQueryObject);
			log.info("关联的模型数据：--{},--{},--{}", dataTempalte, dataTempalte.getContent(), dataTempalte.getTotal());
			if (dataTempalte != null && CollectionUtils.isNotEmpty(dataTempalte.getContent())) {
				map.put(bizProperty.getCode(), dataTempalte.getContent().get(0));
			} else {
				ErrorValue errorValue2 = new ErrorValue();
				errorValue2.setContent(childName + "-" + name + "：关联表单不存在!");
				list.add(errorValue2);
				return;
			}
		}
		return;
	}

	//子表关联表单格式校验
	private void checkChildMultWorkSheet(Map<String, Object> map, Object value, Boolean notEmpty, String name, List<ErrorValue> list, BizPropertyModel bizProperty, String childName) {
		if (notEmpty && Objects.isNull(value)) {
			ErrorValue errorValue1 = new ErrorValue();
			errorValue1.setContent(childName + "-" + name + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue1);
			return;
		}

		String value1 = Objects.isNull(value) ? "" : value.toString();

		if (StringUtils.isNotEmpty(value1)) {
			String[] values = value1.split(";");
			String ids = "";

			for (int multChildIdIndex = 0; multChildIdIndex < values.length; multChildIdIndex++) {
				FilterExpression filterExpression = Q.it("name", FilterExpression.Op.Eq, values[multChildIdIndex]);
				BizObjectQueryModel bizObjectQueryObject = new BizObjectQueryModel();
				PageableImpl pageable = new PageableImpl(0, Integer.MAX_VALUE);
				String s = ReflectionToStringBuilder.toString(bizProperty, ToStringStyle.SHORT_PREFIX_STYLE);
				log.info("bizProperty关联表单的数据：schemaCode={}", JSONObject.toJSONString(bizProperty.getRelativeCode()));
				bizObjectQueryObject.setSchemaCode(bizProperty.getRelativeCode());
				bizObjectQueryObject.setFilterExpr(filterExpression);
				bizObjectQueryObject.setPageable(pageable);
				BizQueryModel bizQuery = getBizQuery(bizProperty.getRelativeCode(), null, ClientType.PC);
				bizObjectQueryObject.setQueryCode(bizQuery.getCode());
				log.info("关联的code：--{}", bizQuery.getCode());
				bizObjectQueryObject.setClientType(ClientType.PC);
				Page<BizObjectModel> dataTempalte = getBizObjectFacade().queryBizObjects(bizObjectQueryObject);
				log.info("关联的模型数据：--{},--{},--{}", dataTempalte, dataTempalte.getContent(), dataTempalte.getTotal());

				if (dataTempalte != null && CollectionUtils.isNotEmpty(dataTempalte.getContent())) {
					ids = ids + dataTempalte.getContent().get(0).getId() + ";";
				} else {
					ErrorValue errorValue2 = new ErrorValue();
					errorValue2.setContent(childName + "-" + name + "：关联表单多选不存在!");
					list.add(errorValue2);
					return;
				}
			}
			ids = ids.substring(0, ids.length() - 1);
			map.put(bizProperty.getCode(), ids);
		}
	}

	//关联表单格式校验
	private void checkWorkSheet(Map<String, Object> params, Map<String, Object> map, Map<String, Object> workSheet) {

		//参数拿出来
		int i = (int) params.get("i");
		Boolean notEmpty = (boolean) params.get("notEmpty");
		List<String> editCodes = (List<String>) params.get("editCodes");
		List<ErrorValue> list = (List<ErrorValue>) params.get("list");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = String.valueOf(params.get("value"));
		List<String> headers = (List<String>) params.get("headers");
		params.get("key");
		params.get("defaultCodes");
		params.get("textInfos");
		params.get("radioInfos");
		params.get("checkboxInfos");
		params.get("dropdownInfos");
		String name = bizProperty.getName();
		//
		//主表
		Boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		if (notEmpty && StringUtils.isEmpty(value)) {
			ErrorValue errorValue1 = new ErrorValue();
			errorValue1.setContent(name + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue1);
			i++;
			return;
		}
		if (StringUtils.isNotEmpty(value)) {
			if (!isQueryData && !editCodes.contains(bizProperty.getCode())) {
				map.put(bizProperty.getCode(), null);
				i++;
				return;
			}
			FilterExpression filterExpression = Q.it("name", FilterExpression.Op.Eq, value);
			BizObjectQueryModel bizObjectQueryObject = new BizObjectQueryModel();
			PageableImpl pageable = new PageableImpl(0, 10000000);
			log.info("bizProperty关联表单的数据：schemaCode={}", JSONObject.toJSONString(bizProperty.getRelativeCode()));
			bizObjectQueryObject.setSchemaCode(bizProperty.getRelativeCode());
			bizObjectQueryObject.setFilterExpr(filterExpression);
			bizObjectQueryObject.setPageable(pageable);
			BizQueryModel bizQuery = getBizQuery(bizProperty.getRelativeCode(), null, ClientType.PC);
			bizObjectQueryObject.setQueryCode(bizQuery.getCode());
			bizObjectQueryObject.setClientType(ClientType.PC);
			Page<BizObjectModel> dataTempalte = getBizObjectFacade().queryBizObjects(bizObjectQueryObject);
			if (dataTempalte != null && CollectionUtils.isNotEmpty(dataTempalte.getContent())) {
				if (isQueryData) {
					map.put(bizProperty.getCode(), dataTempalte.getContent().get(0).getId());
					workSheet.put(bizProperty.getCode(), dataTempalte.getContent().get(0));
				} else {
					Map<String, Object> mapChild = new HashMap<>();
					mapChild.put("name", value);
					mapChild.put("id", dataTempalte.getContent().get(0).getId());
					mapChild.put("schemaCode", bizProperty.getRelativeCode());
					map.put(bizProperty.getCode(), mapChild);
				}
			} else {
				ErrorValue errorValue2 = new ErrorValue();
				errorValue2.setContent(name + "：关联表单不存在!");
				list.add(errorValue2);
				i++;
				return;
			}
		}
		i++;
		return;

	}

	//导入子表的数值格式校验
	private void checkChildNumerical(Map<String, Object> map, Object value, Boolean notEmpty, String name, List<ErrorValue> list, BizPropertyModel bizProperty, String childName) {
		//参数拿出来
		if (Objects.nonNull(value)) {
			String number = value.toString();
			if (!PropertyValidateHelper.validateNumerical(number, notEmpty)) {
				ErrorValue errorValue3 = new ErrorValue();
				errorValue3.setContent("【" + childName + "-" + name + "】输入格式不对，仅支持整数、1位小数、2位小数、3位小数、4位小数、5位小数、6位小数、7位小数和8位小数共9种数值格式；");
				list.add(errorValue3);
				return;
			}
		}
		if (notEmpty && (Objects.isNull(value))) {
			ErrorValue errorValue15 = new ErrorValue();
			errorValue15.setContent(childName + "-" + name + "：该项仅支持数值填写" + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue15);
			return;
		}
		map.put(bizProperty.getCode(), value == null ? null : value);
	}

	//校验导入的日期格式
	private void checkDate(Map<String, Object> params, Map<String, Object> map) {
		//参数拿出来
		int i = (int) params.get("i");
		List<BizPropertyType> propertyTypes = (List<BizPropertyType>) params.get("propertyTypes");
		boolean notEmpty = (boolean) params.get("notEmpty");
		List<String> editCodes = (List<String>) params.get("editCodes");
		List<ErrorValue> list = (List<ErrorValue>) params.get("list");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = Objects.isNull(params.get("value")) ? "" : params.get("value").toString();
		List<String> headers = (List<String>) params.get("headers");
		String key = String.valueOf(params.get("key"));
		params.get("defaultCodes");
		params.get("textInfos");
		params.get("radioInfos");
		params.get("checkboxInfos");
		params.get("dropdownInfos");
		//
		String name = bizProperty.getName();

		//主表
		boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		if (!isQueryData && !editCodes.contains(bizProperty.getCode())) {
			map.put(bizProperty.getCode(), null);
			i++;
			return;
		}
		if (notEmpty && StringUtils.isEmpty(value)) {
			ErrorValue errorValue16 = new ErrorValue();
			errorValue16.setContent(name + "：该项仅支持日期填写" + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue16);
			i++;
			return;
		}
		if (StringUtils.isNotEmpty(value)) {
			if (!PropertyValidateHelper.isValidDates(value, notEmpty)) {
				ErrorValue errorValue4 = new ErrorValue();
				errorValue4.setContent("【" + name + "】输入格式不对，仅支持" + JSONArray.toJSONString(PropertyValidateHelper.supportsPatterns) + "4种日期格式;");
				list.add(errorValue4);
				i++;
				return;
			}
			map.put(bizProperty.getCode(), value);
			i++;
			return;
		}
		map.put(bizProperty.getCode(), null);
		i++;
		return;
	}

	//校验导入的时间格式
	private void checkTime(Map<String, Object> params, Map<String, Object> map) {
		//参数拿出来
		int i = (int) params.get("i");
		List<BizPropertyType> propertyTypes = (List<BizPropertyType>) params.get("propertyTypes");
		Boolean notEmpty = (boolean) params.get("notEmpty");
		List<String> editCodes = (List<String>) params.get("editCodes");
		List<ErrorValue> list = (List<ErrorValue>) params.get("list");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = Objects.isNull(params.get("value")) ? "" : params.get("value").toString();
		List<String> headers = (List<String>) params.get("headers");
		String key = String.valueOf(params.get("key"));
		params.get("defaultCodes");
		params.get("textInfos");
		params.get("radioInfos");
		params.get("checkboxInfos");
		params.get("dropdownInfos");
		//
		String name = bizProperty.getName();

		//主表
		Boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		if (!isQueryData && !editCodes.contains(bizProperty.getCode())) {
			map.put(bizProperty.getCode(), null);
			i++;
			return;
		}
		if (notEmpty && StringUtils.isEmpty(value)) {
			ErrorValue errorValue16 = new ErrorValue();
			errorValue16.setContent(name + "：该项仅支持时间填写" + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue16);
			i++;
			return;
		}
		if (StringUtils.isNotEmpty(value)) {

			if (!PropertyValidateHelper.isValidTime(value, notEmpty)) {
				ErrorValue errorValue4 = new ErrorValue();
				errorValue4.setContent("【" + name + "】输入格式不对，仅支持" + JSONArray.toJSONString(PropertyValidateHelper.supportsTimePatterns) + "2种时间格式;");
				list.add(errorValue4);
				i++;
				return;
			}
			map.put(bizProperty.getCode(), value);
			i++;
			return;
		}
		map.put(bizProperty.getCode(), null);
		i++;
		return;
	}

	//校验导入子表的日期格式
	private void checkChildDate(Map<String, Object> map, Object value, Boolean notEmpty, String name, List<ErrorValue> list, BizPropertyModel bizProperty, String childName) {

		if (notEmpty && Objects.isNull(value)) {
			ErrorValue errorValue16 = new ErrorValue();
			errorValue16.setContent(childName + "-" + name + "：该项仅支持日期填写" + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue16);
			return;
		}

		if (Objects.nonNull(value)) {
			String string = value.toString();
			if (!PropertyValidateHelper.isValidDates(string, notEmpty)) {
				ErrorValue errorValue4 = new ErrorValue();
				errorValue4.setContent("【" + childName + "-" + name + "】输入格式不对，仅支持" + JSONArray.toJSONString(PropertyValidateHelper.supportsPatterns) + "4种日期格式;");
				list.add(errorValue4);
				return;
			}
			map.put(bizProperty.getCode(), value);
			return;
		}
		map.put(bizProperty.getCode(), null);
		return;
	}

	//校验导入的逻辑类型数据格式
	private void checkLogical(Map<String, Object> params, Map<String, Object> map) {
		//参数拿出来
		int i = (int) params.get("i");
		List<BizPropertyType> propertyTypes = (List<BizPropertyType>) params.get("propertyTypes");
		Boolean notEmpty = (boolean) params.get("notEmpty");
		List<String> editCodes = (List<String>) params.get("editCodes");
		List<ErrorValue> list = (List<ErrorValue>) params.get("list");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = Objects.isNull(params.get("value")) ? "" : params.get("value").toString();
		List<String> headers = (List<String>) params.get("headers");
		String key = String.valueOf(params.get("key"));
		params.get("defaultCodes");
		params.get("textInfos");
		params.get("radioInfos");
		params.get("checkboxInfos");
		params.get("dropdownInfos");
		//
		String name = bizProperty.getName();

		//主表
		boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		if (!isQueryData && !editCodes.contains(bizProperty.getCode())) {
			map.put(bizProperty.getCode(), null);
			i++;
			return;
		}
		value = map.get(key) == null ? "" : map.get(key).toString();
		if (!PropertyValidateHelper.validateLogical(value, notEmpty)) {
			ErrorValue errorValue5 = new ErrorValue();
			Object mapValue = (map.get(key) == null) ? "" : "-[" + map.get(key) + "]";
			errorValue5.setContent(name + (notEmpty ? ",不能为空!" : ",可以为空!") + "内容格式错误" + mapValue + "," + "支持类型为：" + JSONArray.toJSONString(PropertyValidateHelper.boolStringValues));
			list.add(errorValue5);
			i++;
			return;
		}
		if (!isQueryData) {
			if ("是".equals(value) || "1".equals(value) || "true".equals(value)) {
				map.put(bizProperty.getCode(), true);
			} else if ("否".equals(value) || "0".equals(value) || "false".equals(value)) {
				map.put(bizProperty.getCode(), false);
			}
		} else {
			if ("是".equals(value) || "1".equals(value) || "true".equals(value)) {
				map.put(bizProperty.getCode(), true);
			} else if ("否".equals(value) || "0".equals(value) || "false".equals(value)) {
				map.put(bizProperty.getCode(), false);
			}
		}
		i++;
		return;
	}

	//校验导入的子表逻辑类型数据格式
	private void checkChildLogical(Map<String, Object> map, Object value, Boolean notEmpty, String name, List<ErrorValue> list, BizPropertyModel bizProperty, String childName) {
		String values = Objects.isNull(value) ? "" : value.toString();
		if (!PropertyValidateHelper.validateLogical(String.valueOf(values), notEmpty)) {
			ErrorValue errorValue5 = new ErrorValue();
			Object mapValue = (Objects.isNull(value)) ? "" : "-[" + value + "]";
			errorValue5.setContent(childName + "-" + name + (notEmpty ? ",不能为空!" : ",可以为空!") + "内容格式错误" + mapValue + "," + "支持类型为：" + JSONArray.toJSONString(PropertyValidateHelper.boolStringValues));
			list.add(errorValue5);
			return;
		}
		if ("是".equals(value) || "1".equals(value) || "true".equals(value)) {
			map.put(bizProperty.getCode(), true);
		} else if ("否".equals(value) || "0".equals(value) || "false".equals(value)) {
			map.put(bizProperty.getCode(), false);
		}
	}

	//校验导入的长文本数据格式
	@SuppressWarnings("unckecked")
	private void checkLongText(Map<String, Object> params, Map<String, Object> map, Map<String, String> textInfos) {
		//参数拿出来
		int i = (int) params.get("i");
		boolean notEmpty = (boolean) params.get("notEmpty");
		List<String> editCodes = (List<String>) params.get("editCodes");
		List<ErrorValue> list = (List<ErrorValue>) params.get("list");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = Objects.isNull(params.get("value")) ? "" : params.get("value").toString();
		String name = bizProperty.getName();

		//主表
		boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}

		if (notEmpty && StringUtils.isEmpty(value)) {
			ErrorValue errorValue20 = new ErrorValue();
			errorValue20.setContent(name + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue20);
			i++;
			return;
		}

		Integer maxLength = 16777215;
		if (!PropertyValidateHelper.validateShortText(value, maxLength, notEmpty)) {
			ErrorValue errorValue6 = new ErrorValue();
			errorValue6.setContent(name + "：长文本数据类型，内容太多，超出16777215个字符限制，请修改！");
			list.add(errorValue6);
			i++;
			return;
		}

		if (!isQueryData) {
			if (CollectionUtils.isNotEmpty(textInfos.keySet()) && textInfos.containsKey(bizProperty.getCode())) {
				if (value.length() > Integer.parseInt(textInfos.get(bizProperty.getCode()))) {
					map.put(bizProperty.getCode(), value.substring(0, Integer.parseInt(textInfos.get(bizProperty.getCode()))));
					i++;
					return;
				}
			}
		}
		map.put(bizProperty.getCode(), value);
		i++;
		return;
	}

	//关联表单多选格式校验
	private void checkMultWorkSheet(Map<String, Object> params, Map<String, Object> map, Map<String, Object> workSheet) {

		//参数拿出来
		int i = (int) params.get("i");
		Boolean notEmpty = (boolean) params.get("notEmpty");
		List<String> editCodes = (List<String>) params.get("editCodes");
		List<ErrorValue> list = (List<ErrorValue>) params.get("list");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = String.valueOf(params.get("value"));
		List<String> headers = (List<String>) params.get("headers");
		params.get("key");
		params.get("defaultCodes");
		params.get("textInfos");
		params.get("radioInfos");
		params.get("checkboxInfos");
		params.get("dropdownInfos");
		Map<String, Object> multWorkMap = (Map<String, Object>) params.get("multWorkMap");
		String name = bizProperty.getName();
		//
		//主表
		Boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		if (notEmpty && StringUtils.isEmpty(value)) {
			ErrorValue errorValue1 = new ErrorValue();
			errorValue1.setContent(name + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue1);
			i++;
			return;
		}
		if (StringUtils.isNotEmpty(value)) {
			if (!isQueryData && !editCodes.contains(bizProperty.getCode())) {
				map.put(bizProperty.getCode(), null);
				i++;
				return;
			}
			String[] values = value.split(";");
			String ids = "";
			String names = "";
			String showName = "";
			for (int multIdIndex = 0; multIdIndex < values.length; multIdIndex++) {
				String multName = values[multIdIndex];
				FilterExpression filterExpression = Q.it("name", FilterExpression.Op.Eq, multName);
				BizObjectQueryModel bizObjectQueryObject = new BizObjectQueryModel();
				PageableImpl pageable = new PageableImpl(0, 10000000);
				log.info("bizProperty关联表单的数据：schemaCode={}", JSONObject.toJSONString(bizProperty.getRelativeCode()));
				//对关联表单多选进行特殊处理
				GetBizQueryOptions getBizQueryOptions = new GetBizQueryOptions(bizProperty, multWorkMap).invoke();
				BizObjectQueryModel.Options options = getBizQueryOptions.getOptions();
				List<String> queryCodes = getBizQueryOptions.getQueryCodes();
				queryCodes.add(bizProperty.getRelativePropertyCode());
				bizObjectQueryObject.setOptions(options);
				bizObjectQueryObject.setSchemaCode(bizProperty.getRelativeCode());
				bizObjectQueryObject.setFilterExpr(filterExpression);
				bizObjectQueryObject.setPageable(pageable);
				BizQueryModel bizQuery = getBizQuery(bizProperty.getRelativeCode(), null, ClientType.PC);
				bizObjectQueryObject.setQueryCode(bizQuery.getCode());
				bizObjectQueryObject.setClientType(ClientType.PC);
				Page<BizObjectModel> dataTempalte = getBizObjectFacade().queryBizObjects(bizObjectQueryObject);
				if (dataTempalte != null && CollectionUtils.isNotEmpty(dataTempalte.getContent())) {
					//关联表单多选ID都是;分割
					ids = ids + dataTempalte.getContent().get(0).getId() + ";";
					if (dataTempalte.getContent().get(0).getData().get(bizProperty.getRelativePropertyCode()) != null) {
						showName = showName + dataTempalte.getContent().get(0).getData().get(bizProperty.getRelativePropertyCode()) + ";";
					}
					//目标模型数据只取第一个
					BizObjectModel bizObjectModel = dataTempalte.getContent().get(0);
					if (Objects.nonNull(multWorkMap.get(bizProperty.getCode() + "_mappingKeys"))) {
						queryCodes.remove("id");
						queryCodes.remove(bizProperty.getRelativePropertyCode());
						queryCodes.stream().forEach(queryCode -> {
							//取当前的子表schemaCode
							String childCode = (String) multWorkMap.get(bizProperty.getCode() + "_" + queryCode);
							//取相同的子表字段
							List<String> sameCodes = (List<String>) multWorkMap.get(bizProperty.getCode() + "_" + queryCode + "_list");
							//取目标模型子表数据
							List<Map<String, Object>> childDatas = (List<Map<String, Object>>) bizObjectModel.getData().get(queryCode);
							//用相同的子表字段组装当前表单的子表数据
							List<Map<String, Object>> newChildDatas = Lists.newArrayList();
							childDatas.stream().forEach(childData -> {
								Map<String, Object> targetMap = Maps.newHashMap();
								//targetMap.put("id",childData.get("id"));
								sameCodes.stream().forEach(sameCode -> targetMap.put(sameCode, childData.get(sameCode)));
								newChildDatas.add(targetMap);

							});
							map.put(childCode, newChildDatas);
						});
					}
				} else {
					ErrorValue errorValue2 = new ErrorValue();
					errorValue2.setContent(name + "：关联表单多选不存在!");
					list.add(errorValue2);
					i++;
					return;
				}
			}
			ids = ids.substring(0, ids.length() - 1);
			if (StringUtils.isNotBlank(showName)) {
				showName = showName.substring(0, showName.length() - 1);
			}
			if (isQueryData) {
				map.put(bizProperty.getCode(), ids);
			} else {
				Map<String, Object> mapChild = new HashMap<>();
				mapChild.put("name", value);
				mapChild.put("showName", showName);
				mapChild.put("id", ids);
				mapChild.put("schemaCode", bizProperty.getRelativeCode());
				map.put(bizProperty.getCode(), mapChild);
			}

		}
		i++;
		return;

	}

	//校验导入子表的长文本数据格式
	private void checkChildLongText(Map<String, Object> map, Object value, Boolean notEmpty, String name, List<ErrorValue> list, BizPropertyModel bizProperty, String childName) {
		//参数拿出来
		if (notEmpty && Objects.isNull(value)) {
			ErrorValue errorValue20 = new ErrorValue();
			errorValue20.setContent(childName + "-" + name + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue20);
			return;
		}
		String values = Objects.isNull(value) ? "" : value.toString();
		Integer maxLength = 16777215;
		if (!PropertyValidateHelper.validateShortText(String.valueOf(values), maxLength, notEmpty)) {
			ErrorValue errorValue6 = new ErrorValue();
			errorValue6.setContent(childName + "-" + name + "：长文本数据类型，内容太多，超出16777215个字符限制，请修改！");
			list.add(errorValue6);
			return;
		}
		map.put(bizProperty.getCode(), value);
	}

	//说明：未更改成功的数据结构：放入一个CompMatchInfo对象，之前是一个值，如null
	//见代码：map.put(bizProperty.getCode(),new CompMatchInfo<String>(null,true));
	//原有匹配成功数据结构："Province": "河北省"，未匹配数据结构："Province": {"value": null,"marked": true }

	//校验业务项短文本和系统数据项短文本
	@SuppressWarnings("unchecked")
	private void checkShortText(List<String> defaultCodes, Map<String, String> textInfos,
								Map<String, String> radioInfos, Map<String, String> checkboxInfos,
								Map<String, String> dropdownInfos, Map<String, Object> params, Map<String, Object> map,
								FileOperationResult operationResult, Map<String, Map<String, String>> dropdownInfos2,
								BizFormModel bizFormModel) {

		//参数拿出来
		int i = (int) params.get("i");
		boolean notEmpty = (boolean) params.get("notEmpty");
		List<String> editCodes = (List<String>) params.get("editCodes");
		List<ErrorValue> list = (List<ErrorValue>) params.get("list");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = Objects.isNull(params.get("value")) ? "" : params.get("value").toString();
		String key = String.valueOf(params.get("key"));
		String name = bizProperty.getName();


		//主表
		boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		if (!isQueryData && !editCodes.contains(bizProperty.getCode())) {
			map.put(bizProperty.getCode(), null);
			i++;
			return;
		}
		//需要校验长度
		if (notEmpty && StringUtils.isEmpty(value)) {
			ErrorValue errorValue17 = new ErrorValue();
			errorValue17.setContent(name + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue17);
			i++;
			return;
		}
		Integer maxLength = 200;
		if (!PropertyValidateHelper.validateShortText(value, maxLength, notEmpty)) {
			ErrorValue errorValue6 = new ErrorValue();
			errorValue6.setContent(name + "：为短文本数据类型，内容太多，超出200个字符限制，请修改！");
			list.add(errorValue6);
			i++;
			return;
		}
		//todo:测试和产品确认
		//系统数据项人或部门

		if (StringUtils.isNotEmpty(value) && defaultCodes.contains(bizProperty.getCode())) {
			if (bizProperty.getCode().equals(DefaultPropertyType.SEQUENCE_STATUS.getCode())) {
				if (value.equals(WorkflowInstanceStatus.DRAFT.getName()) || value.equals(String.valueOf(WorkflowInstanceStatus.DRAFT.getIndex())) || value.equals(WorkflowInstanceStatus.DRAFT.name())) {
					value = WorkflowInstanceStatus.DRAFT.name();
					map.put(DefaultPropertyType.SEQUENCE_STATUS.getCode(), value);
				} else if (value.equals(WorkflowInstanceStatus.COMPLETED.getName()) || value.equals(String.valueOf(WorkflowInstanceStatus.COMPLETED.getIndex())) || value.equals(WorkflowInstanceStatus.COMPLETED.name())) {
					value = WorkflowInstanceStatus.COMPLETED.name();
					map.put(DefaultPropertyType.SEQUENCE_STATUS.getCode(), value);
				} else {
					if (StringUtils.isEmpty(value)) {
						value = WorkflowInstanceStatus.DRAFT.name();
						map.put(DefaultPropertyType.SEQUENCE_STATUS.getCode(), value);
					} else {
						ErrorValue errorValue7 = new ErrorValue();
						Object mapValue = (map.get(key) == null) ? "" : "-[" + map.get(key) + "]";
						errorValue7.setContent(name + (notEmpty ? ",不能为空!" : ",可以为空!") + "内容格式错误" + mapValue + "," + "不支持数字填写，填写内容可为：草稿，已完成");
						list.add(errorValue7);
						i++;
						return;
					}
				}
			}
		} else {
			//子表导入，非列表带入，匹配
			if (!isQueryData && StringUtils.isNotEmpty(value)) {
				if (CollectionUtils.isNotEmpty(textInfos.keySet()) && textInfos.keySet().contains(bizProperty.getCode())) {
					if (value.length() > Integer.parseInt(textInfos.get(bizProperty.getCode()))) {
						map.put(bizProperty.getCode(), value.substring(0, Integer.parseInt(textInfos.get(bizProperty.getCode()))));
						i++;
						return;
					}
				}
				if (CollectionUtils.isNotEmpty(radioInfos.keySet()) && radioInfos.keySet().contains(bizProperty.getCode())) {
					if (!Arrays.asList(radioInfos.get(bizProperty.getCode()).split(";")).contains(value)) {
						//map.put(bizProperty.getCode(), null);
						map.put(bizProperty.getCode(), new CompMatchInfo<String>(null, true));
						operationResult.setRadioMarkedCount(operationResult.getRadioMarkedCount() + 1);
						i++;
						return;
					}
				}
				//if (CollectionUtils.isNotEmpty(dropdownInfos.keySet()) && dropdownInfos.keySet().contains(bizProperty.getCode())) {
				if (CollectionUtils.isNotEmpty(dropdownInfos2.keySet()) && dropdownInfos2.keySet().contains(bizProperty.getCode())) {
					//String setting = dropdownInfos.get(bizProperty.getCode());
					Map<String, String> smap = dropdownInfos2.get(bizProperty.getCode());
					String setting = smap.get(bizProperty.getCode());

					//multi 排除下拉框多选,之前下拉框多选有问题
					boolean isSchemaDropdown = setting != null && setting.contains("schemaCode") && setting.contains("appCode") && setting.contains("sheetDataItem") && !setting.contains(";");
					//if (!isSchemaDropdown && !Arrays.asList(dropdownInfos.get(bizProperty.getCode()).split(";")).contains(value)) {
					if (!isSchemaDropdown && !Arrays.asList(smap.get(bizProperty.getCode()).split(";")).contains(value)
							&& "false".equals(smap.get("multi"))) {
						//map.put(bizProperty.getCode(), null);
						map.put(bizProperty.getCode(), new CompMatchInfo<String>(null, true));
						operationResult.setDropdownMarkedCount(operationResult.getDropdownMarkedCount() + 1);
						i++;
						return;
					} else if (!isSchemaDropdown && "true".equals(smap.get("multi"))) {//下拉框多选
						List<String> multiValue = new ArrayList<>();
						Collections.addAll(multiValue, value.split(";"));
						List<String> settingList = Arrays.asList(smap.get(bizProperty.getCode()).split(";"));
						boolean rm = multiValue.retainAll(settingList);
						if (rm) {
							map.put(bizProperty.getCode(), new CompMatchInfo<>(String.join(";", multiValue), true));
							operationResult.setDropdownMarkedCount(operationResult.getDropdownMarkedCount() + 1);
							return;
						}
					}
				}
				if (CollectionUtils.isNotEmpty(checkboxInfos.keySet()) && checkboxInfos.keySet().contains(bizProperty.getCode())) {
					List<String> defaultInfors = new ArrayList<>();
					Collections.addAll(defaultInfors, checkboxInfos.get(bizProperty.getCode()).split(";"));
					List<String> valueInfors = new ArrayList<>();
					Collections.addAll(valueInfors, value.split(";"));
					boolean r = valueInfors.retainAll(defaultInfors);
					//保持只有不匹配的才修改
					if (r) {
						map.put(bizProperty.getCode(), new CompMatchInfo<>(valueInfors.stream().collect(Collectors.joining(";")), true));
						operationResult.setCheckboxMarkedCount(operationResult.getCheckboxMarkedCount() + 1);
					} else {
						map.put(bizProperty.getCode(), value);
					}
					//map.put(bizProperty.getCode(), valueTem.stream().collect(Collectors.joining(";")));
					i++;
					return;
				}
			}

			//主表
			if (isQueryData && StringUtils.isNotEmpty(value)) {
				String matchValue = validateShortTextData(bizFormModel, value, bizProperty);
				map.put(bizProperty.getCode(), matchValue);
				return;
			}
		}
		map.put(bizProperty.getCode(), value);
		i++;
	}

	//校验主表单选框，复选框，下拉单选，下拉多选是否匹配
	private String validateShortTextData(BizFormModel bizFormModel, String value, BizPropertyModel bizProperty) {
		String matchValue = value;
		String code = bizProperty.getCode();
		String publishedAttributesJsonStr = bizFormModel.getPublishedAttributesJson();
		JSONObject publishedAttributesJson = JSONObject.parseObject(publishedAttributesJsonStr);
		if (Objects.isNull(publishedAttributesJson)) {
			return matchValue;
		}
		CompProperty compProperty = JSON.parseObject(publishedAttributesJson.getString(code), CompProperty.class);
		//在数据项中存在，但在表单中不存在时
		if (Objects.isNull(compProperty)) {
			return matchValue;
		}
		Integer type = compProperty.getType();
		CompProperty.Option options1 = compProperty.getOptions();
		String options2 = options1.getOptions();
		//处理控件与配置不匹配的数据
		if ((type == BizFormPropertyType.RADIO.getIndex()
				|| type == BizFormPropertyType.CHECKBOX.getIndex()
				|| type == BizFormPropertyType.SELECT.getIndex())
				&& StringUtils.isNotEmpty(options2)) {
			String regex = ";";
			String delimiter = ";";
			List<String> options2List = Arrays.asList(options2.split(regex));
			if (type == BizFormPropertyType.SELECT.getIndex()) {//下拉框
				boolean isSchemaDropdown = options2 != null && options2.contains("schemaCode")
						&& options2.contains("appCode") && options2.contains("sheetDataItem") && !options2.contains(";");
				if (!isSchemaDropdown && !options1.getMulti() && !options2List.contains(value)) {//下拉框单选
					matchValue = null;
				} else if (!isSchemaDropdown && options1.getMulti()) {//下拉框多选
					List<String> multiValue = new ArrayList<>();
					Collections.addAll(multiValue, value.split(regex));
					multiValue.retainAll(options2List);
					matchValue = String.join(delimiter, multiValue);
				}
			} else if (type == BizFormPropertyType.RADIO.getIndex()) {//单选框
				if (!options2List.contains(value)) {
					matchValue = null;
				}
			} else if (type == BizFormPropertyType.CHECKBOX.getIndex()) {//多选框
				List<String> ckList = new ArrayList<>();
				Collections.addAll(ckList, value.split(regex));
				if (ckList.retainAll(options2List)) {
					matchValue = String.join(delimiter, ckList);
				}
			}
		}
		return matchValue;
	}


	//校验子表业务项短文本和系统数据项短文本
	private void checkChildShortText(List<String> defaultCodes, Map<String, Object> map, Object value
			, Boolean notEmpty, String name, List<ErrorValue> list, BizPropertyModel bizProperty
			, String childName, BizFormModel bizFormModel, String code) {

		//需要校验长度
		if (notEmpty && Objects.isNull(value)) {
			ErrorValue errorValue17 = new ErrorValue();
			errorValue17.setContent(childName + "-" + name + (notEmpty ? ",不能为空!" : ",可以为空!"));
			list.add(errorValue17);
			return;
		}
		String values = Objects.isNull(value) ? "" : value.toString();
		Integer maxLength = 200;
		if (!PropertyValidateHelper.validateShortText(values, maxLength, notEmpty)) {
			ErrorValue errorValue6 = new ErrorValue();
			errorValue6.setContent(childName + "-" + name + "：为短文本数据类型，内容太多，超出200个字符限制，请修改！");
			list.add(errorValue6);
			return;
		}
		//todo:测试和产品确认
		//系统数据项人或部门
		if (Objects.nonNull(value) && defaultCodes.contains(bizProperty.getCode())) {
			if (bizProperty.getCode().equals(DefaultPropertyType.SEQUENCE_STATUS.getCode())) {
				if (value.equals(WorkflowInstanceStatus.DRAFT.getName()) || value.equals(String.valueOf(WorkflowInstanceStatus.DRAFT.getIndex())) || value.equals(WorkflowInstanceStatus.DRAFT.name())) {
					value = WorkflowInstanceStatus.DRAFT.name();
					map.put(DefaultPropertyType.SEQUENCE_STATUS.getCode(), value);
				} else if (value.equals(WorkflowInstanceStatus.COMPLETED.getName()) || value.equals(String.valueOf(WorkflowInstanceStatus.COMPLETED.getIndex())) || value.equals(WorkflowInstanceStatus.COMPLETED.name())) {
					value = WorkflowInstanceStatus.COMPLETED.name();
					map.put(DefaultPropertyType.SEQUENCE_STATUS.getCode(), value);
				} else {
					if (Objects.isNull(value)) {
						value = WorkflowInstanceStatus.DRAFT.name();
						map.put(DefaultPropertyType.SEQUENCE_STATUS.getCode(), value);
					} else {
						ErrorValue errorValue7 = new ErrorValue();
						Object mapValue = (Objects.isNull(value)) ? "" : "-[" + value + "]";
						errorValue7.setContent(childName + "-" + name + (notEmpty ? ",不能为空!" : ",可以为空!") + "内容格式错误" + mapValue + "," + "不支持数字填写，填写内容可为：草稿，已完成");
						list.add(errorValue7);
						return;
					}
				}
			}
		} else {
			map.put(bizProperty.getCode(), value);

			//子表控件数据校验
			String publishedAttributesJsonStr = bizFormModel.getPublishedAttributesJson();
			JSONObject publishedAttributesJson = JSONObject.parseObject(publishedAttributesJsonStr);
			if (Objects.isNull(publishedAttributesJson)) {
				map.put(bizProperty.getCode(), value);
				return;
			}
			JSONObject childTable = publishedAttributesJson.getJSONObject(code);
			if (Objects.isNull(childTable)) {
				return;
			}
			JSONArray jsonArray = childTable.getJSONArray("columns");

			List<CompProperty> compProperties = JSONObject.parseArray(JSON.toJSONString(jsonArray), CompProperty.class);
			Optional<CompProperty> compPropertyOptional = compProperties.stream().filter(t -> t.getKey().equals(bizProperty.getCode())).findFirst();
			//在数据项中存在，表单中不存在时
			if (!compPropertyOptional.isPresent()) {
				map.put(bizProperty.getCode(), value);
				return;
			}
			CompProperty compProperty = compPropertyOptional.get();
			Integer type = compProperty.getType();
			CompProperty.Option options1 = compProperty.getOptions();
			String options2 = options1.getOptions();
			//处理控件与配置不匹配的数据
			if (type == 5 || type == 6 || type == 7) {
				if (StringUtils.isEmpty(options2)) {
					map.put(bizProperty.getCode(), null);
				} else {
					List<String> options2List = Arrays.asList(options2.split(";"));
					if (type == 7) {//下拉框
						boolean isSchemaDropdown = options2 != null && options2.contains("schemaCode")
								&& options2.contains("appCode") && options2.contains("sheetDataItem") && !options2.contains(";");
						if (!isSchemaDropdown && !options1.getMulti() && !options2List.contains(values)) {//下拉框单选
							map.put(bizProperty.getCode(), null);
						} else if (!isSchemaDropdown && options1.getMulti()) {//下拉框多选
							List<String> multiValue = new ArrayList<>();
							Collections.addAll(multiValue, value.toString().split(";"));
							multiValue.retainAll(options2List);
							map.put(bizProperty.getCode(), String.join(";", multiValue));
						}
					} else if (type == 5) {//单选框
						if (!options2List.contains(value)) {
							map.put(bizProperty.getCode(), null);
						}
					} else if (type == 6) {//多选框
						List<String> ckList = new ArrayList<>();
						if (StringUtils.isBlank(values)) {
							map.put(bizProperty.getCode(), null);
							return;
						}
						Collections.addAll(ckList, value.toString().split(";"));
						if (ckList.retainAll(options2List)) {
							map.put(bizProperty.getCode(), String.join(";", ckList));
						}
					}
					//class
				}//end else
				return;
			}

		}//
		map.put(bizProperty.getCode(), value);
	}

	// 校验子表导入的选人控件的数据格式
	private boolean checkFormSelection(Map<String, Object> params, Map<String, Object> map, String userId, String corpId, DepartmentModel rootDept, boolean success, OrgType orgType) {
		//参数拿出来
		int i = (int) params.get("i");
		List<String> editCodes = (List<String>) params.get("editCodes");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = Objects.isNull(params.get("value")) ? "" : params.get("value").toString();
		//主表
		boolean isQueryData = true;
		//表单子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		//为表单子表导入  /但是子表传入的数据项列表不包含  该编码
		if (!isQueryData && !editCodes.contains(bizProperty.getCode())) {
			map.put(bizProperty.getCode(), null);
			i++;
			return true;
		}
		String[] selections = value.split(";");
		//选人控件
		List<SelectionValue> selectionValues = new ArrayList<>();
		for (String selection : selections) {
			success = parseSelections(selection, rootDept, orgType, selectionValues, success, corpId);
		}
		map.put(bizProperty.getCode(), selectionValues);
		i++;
		return success;
	}

	private boolean parseUserSelections(String selection, List<SelectionValue> selectionValues, boolean success, String corpId, OrgType orgType) {
		String[] split = selection.split("\\.");
		//部门是否已经禁用
		boolean isDeptForbidden = false;
		List<UserModel> users = null;
		if (split.length < 2) {
			users = getOrganizationFacade().searchUsersByName(selection);
		}
		if (split.length == 2) {
			List<String> departmentIds = null;
			List<DepartmentModel> departmentModels = getOrganizationFacade().searchDepartmentByDepartmentName(split[1]);
			if (CollectionUtils.isNotEmpty(departmentModels)) {
				departmentIds = departmentModels.stream().filter(t -> !Objects.isNull(t) && Objects.equals(split[1], t.getName())).map(t -> t.getId()).collect(Collectors.toList());

				DepartmentModel departmentModel1 = departmentModels.stream().filter(departmentModel -> !departmentModel.getEnabled()).findFirst().orElse(null);
				isDeptForbidden = departmentModel1 != null;
			}
			if (CollectionUtils.isNotEmpty(departmentIds)) {
				users = getOrganizationFacade().searchUsersByNameAndDepartmentIds(split[0], departmentIds);
			}
		}
		if (CollectionUtils.isNotEmpty(users)) {
			users = users.stream().filter(userModel -> UserStatus.ENABLE == userModel.getStatus() && userModel.getName().equals(split[0])).collect(Collectors.toList());
			if (orgType != OrgType.MAIN && CollectionUtils.isNotEmpty(users)) {
				users = users.stream().filter(userModel -> Objects.equals(userModel.getCorpId(), corpId)).collect(Collectors.toList());
			}
		}

		SelectionValue selectionValue = new SelectionValue();
		if (isDeptForbidden) {
			parseSelectionValue(selectionValue, UnitType.USER, null, ExcelType.FORBIDDEN, split[0]);
			success = false;
			selectionValues.add(selectionValue);
		} else if (CollectionUtils.isEmpty(users) || users.size() < 1) {
			parseSelectionValue(selectionValue, UnitType.USER, null, ExcelType.NOEXIT, split[0]);
			success = false;
			selectionValues.add(selectionValue);
		} else if (users.size() > 1) {
			parseSelectionValue(selectionValue, UnitType.USER, null, ExcelType.REPEAT, split[0]);
			success = false;
			selectionValues.add(selectionValue);
		} else {
			parseSelectionValue(selectionValue, UnitType.USER, users.get(0).getId(), null, split[0]);
			selectionValues.add(selectionValue);
		}
		return success;
	}

	//校验导入的选人控件的数据格式
	private boolean checkSelection(List<String> defaultCodes, Map<String, Object> params, Map<String, Object> map, boolean success, String corpId, String userId, DepartmentModel rootDeptName, OrgType orgType) {
		//参数拿出来
		int i = (int) params.get("i");
		boolean notEmpty = (boolean) params.get("notEmpty");
		List<String> editCodes = (List<String>) params.get("editCodes");
		BizPropertyModel bizProperty = (BizPropertyModel) params.get("bizProperty");
		String value = Objects.isNull(params.get("value")) ? "" : params.get("value").toString();
		//主表
		boolean isQueryData = true;
		//子表
		if (CollectionUtils.isNotEmpty(editCodes)) {
			isQueryData = false;
		}
		if (StringUtils.isEmpty(value)) {
			if (notEmpty) {
				SelectionValue selectionValue = new SelectionValue();
				parseSelectionValue(selectionValue, UnitType.USER, null, ExcelType.EMPTY, null);
				success = false;
				map.put(bizProperty.getCode(), Lists.newArrayList(selectionValue));
				i++;
				return success;
			}
			map.put(bizProperty.getCode(), null);
			i++;
			return success;
		}
		//表单子表
		if (!isQueryData) {
			success = checkFormSelection(params, map, userId, corpId, rootDeptName, success, orgType);
			return success;
		} else {
			//列表主表
			//获取excel填写的值，多选之间设定是用英文分号符分隔
			String[] selections = value.split(";");
			//处理默认数据项选人控件
			if (defaultCodes.contains(bizProperty.getCode())) {
				List<SelectionValue> selectionValues = new ArrayList<>();
				success = parseSelections(selections[0], rootDeptName, orgType, selectionValues, success, corpId);
				i++;
				map.put(bizProperty.getCode(), selectionValues);
				return success;
			}
			//表单选人控件
			List<SelectionValue> selectionValues = new ArrayList<>();
			for (String selection : selections) {
				//封装下
				success = parseSelections(selection, rootDeptName, orgType, selectionValues, success, corpId);
			}
			map.put(bizProperty.getCode(), selectionValues);
			i++;
			return success;
		}
	}

	private void parseSelectionValue(SelectionValue selectionValue, UnitType unitType, String id, ExcelType excelType, String name) {
		selectionValue.setId(id);
		selectionValue.setName(name);
		selectionValue.setType(unitType);
		selectionValue.setExcelType(excelType);
	}

	private boolean parseSelections(String selection, DepartmentModel rootDeptName, OrgType orgType, List<SelectionValue> selectionValues, boolean success, String corpId) {
		List<String> departNames = StrUtil.splitTrim(selection, "/");
		log.debug("获取到的部门或者用户名称为{}", selection);
		//区分根节点和其他路径
		Map<String, String> mapDepart = new HashMap<>();
		boolean repeat = false;
		if (CollectionUtils.isNotEmpty(departNames)) {
			if (departNames.size() == 1) {
				String departName = departNames.get(0);
				boolean equals = Objects.equals(departName, rootDeptName.getName());
				if (equals) {
					mapDepart.put(rootDeptName.getId(), departName);
				} else {
					List<DepartmentModel> departmentModels = getOrganizationFacade().searchDepartmentByDepartmentName(departName, false);
					if (CollectionUtils.isNotEmpty(departmentModels)) {
						departmentModels = departmentModels.stream().filter(depart -> StringUtils.equals(depart.getName(), departName) && Boolean.TRUE.equals(depart.getEnabled())).collect(Collectors.toList());
						if (departmentModels.size() > 1) {
							repeat = true;
						}
						for (DepartmentModel departmentModel : departmentModels) {
							if (departName.equals(departmentModel.getName())) {
								mapDepart.put(departmentModel.getId(), departName);
							}
						}
					}
				}
			} else {
				mapDepart = getOrganizationFacade().getParentDepartNames(departNames.get(departNames.size() - 1));
			}
		}
		if (MapUtils.isEmpty(mapDepart) || mapDepart.size() < 1) {
			success = parseUserSelections(selection, selectionValues, success, corpId, orgType);
		} else {
			boolean equals = false;
			for (String s : mapDepart.keySet()) {
				if (selection.equals(mapDepart.get(s))) {
					DepartmentModel depart = getOrganizationFacade().getDepartment(s);
					if (!Objects.equals(depart.getEnabled(), Boolean.TRUE)) {
						continue;
					}
					SelectionValue selectionValue = new SelectionValue();
					parseSelectionValue(selectionValue, UnitType.DEPARTMENT, depart.getId(), repeat ? ExcelType.REPEAT : null, depart.getName());
					selectionValues.add(selectionValue);
					equals = true;
				}
			}
			if (!equals) {
				SelectionValue selectionValue = new SelectionValue();
				parseSelectionValue(selectionValue, UnitType.DEPARTMENT, null, ExcelType.NOEXIT, selection);
				selectionValues.add(selectionValue);
				success = equals;
			}
		}
		return success;
	}

	//校验导入的子表选人控件的数据格式
	private boolean checkChildSelection(Map<String, Object> map, Object value, Boolean notEmpty, BizPropertyModel bizProperty,
										boolean ok, String corpId, DepartmentModel rootDept, OrgType orgType) {
		if (Objects.isNull(value)) {
			if (notEmpty) {
				ok = false;
				SelectionValue selectionValue = new SelectionValue();
				selectionValue.setId(null);
				selectionValue.setName(null);
				selectionValue.setType(UnitType.USER);
				selectionValue.setExcelType(ExcelType.EMPTY);
				selectionValue.setDepartmentId(null);
				selectionValue.setDepartments(Lists.newArrayList());
				selectionValue.setParentId(null);
				selectionValue.setImgUrl(null);
				map.put(bizProperty.getCode(), Lists.newArrayList(selectionValue));
				return ok;
			}
			map.put(bizProperty.getCode(), Lists.newArrayList());
			return ok;
		}
		String string = value.toString();
		String[] selections = string.split(";");
		//表单选人控件
		List<SelectionValue> selectionValues = new ArrayList<>();
		for (String selection : selections) {
			ok = parseSelections(selection, rootDept, orgType, selectionValues, ok, corpId);
		}
		map.put(bizProperty.getCode(), selectionValues);
		return ok;
	}

	private Map<String, String> parseAttribute(Map<String, List<String>> attrituteMaps, String key) {
		Map<String, String> mapInfos = new HashMap<>();
		if (CollectionUtils.isNotEmpty(attrituteMaps.get(key))) {
			for (String text : attrituteMaps.get(key)) {
				Map<String, String> map = (Map<String, String>) JSON.parse(text);
				for (String s : map.keySet()) {
					mapInfos.put(s, map.get(s));
				}
			}
		}
		return mapInfos;
	}

	private Map<String, Map<String, String>> parseAttribute_dropdown(Map<String, List<String>> attrituteMaps, String key) {
		Map<String, Map<String, String>> mapInfos = new HashMap<>();
		if (CollectionUtils.isNotEmpty(attrituteMaps.get(key))) {
			for (String text : attrituteMaps.get(key)) {
				Map<String, Map<String, String>> map = (Map<String, Map<String, String>>) JSON.parse(text);
				//Map<String, String> map = (Map<String, String>) JSON.parse(text);
				for (String s : map.keySet()) {
					mapInfos.put(s, map.get(s));
				}
			}
		}
		return mapInfos;
	}

	/**
	 * 过滤出可删除的业务数据
	 *
	 */
	@Override
	protected void disposeDeletePermissions(String userId, String schemaCode, List<String> ids, List<String> noDeleteIds) {
		AppFunctionModel appFunctionModel = getAppManagementFacade().getAppFunctionByCode(schemaCode);
		if (Objects.isNull(appFunctionModel)) {
			throw new PortalException(ErrCode.APP_FUNCTION_MODEL_NOTEXIST.getErrCode(), ErrCode.APP_FUNCTION_MODEL_NOTEXIST.getErrMsg());
		}
		boolean isAdmin;
		boolean isSysManager = false;
		boolean isDataManagerForApp = false;
		if ((isAdmin = isAdmin(userId))
				|| (isSysManager = isSysManager(userId))
				|| (isDataManagerForApp = isDataManagerForApp(userId, schemaCode))) {
			log.debug("admin={},sys_mng={},data_mng={}管理员有删除权限", isAdmin, isSysManager, isDataManagerForApp);
			return;
		}

		log.debug("处理普通用户对数据的删除权限");
		List<AppPackagePermissionModel> appPackagePermissionModels = getPermissionManagementFacade().getAppPackagePermissionsByUserId(userId);
		AppPackagePermissionModel appPackagePermissionModel = appPackagePermissionModels.stream().filter(t -> t.getAppPackage().getCode().equals(appFunctionModel.getAppCode()) && t.getAppPackage().getEnabled() && t.getVisibleType().equals(VisibleType.ALL_VISIABLE)).findAny().orElse(null);
		if (appPackagePermissionModel != null) {
			return;
		}
		List<PermissionGroupModel> permissionGroupModels = getPermissionManagementFacade().getPermissionGroupsByAppCodeAndUserId(appFunctionModel.getAppCode(), userId);
		if (CollectionUtils.isEmpty(permissionGroupModels)) {
			return;
		}
		List<AppFunctionPermissionModel> appFunctionPermissionModels = new ArrayList<>();
		for (PermissionGroupModel permissionGroupModel : permissionGroupModels) {
			List<AppFunctionPermissionModel> appFunctionPermissionModelTemplates = permissionGroupModel.getDataPermissionGroups();
			if (CollectionUtils.isNotEmpty(appFunctionPermissionModelTemplates)) {
				AppFunctionPermissionModel appFunctionPermission = appFunctionPermissionModelTemplates.stream().filter(t -> t.getVisible() && t.getSchemaCode().equals(schemaCode) && t.getDeletable()).findAny().orElse(null);
				if (appFunctionPermission != null) {
					if (appFunctionPermission.getDataPermissionType().equals(DataPermissionType.CUSTOM)) {
						appFunctionPermission.setConditions(getPermissionManagementFacade().getAppFunctionPermissionConditions(schemaCode));
					}
					appFunctionPermissionModels.add(appFunctionPermission);
				}
			}
		}
		if (CollectionUtils.isEmpty(appFunctionPermissionModels)) {
			log.debug("没有配置删除权限无法删除数据");
			ids.clear();
			return;
		}
		List<WorkflowInstanceModel> workflowInstances = getWorkflowInstanceFacade().getWorkflowInstancesByBizObjectId(ids);
		List<String> idsForSheet = workflowInstances.stream().map(WorkflowInstanceModel::getBizObjectId).collect(Collectors.toList());
		if (CollectionUtils.isNotEmpty(workflowInstances)) {
			log.debug("流程表单数据为{}", idsForSheet);
			workflowInstances.forEach(workflowInstanceModel -> {
				//发起人可以删除草稿状态的数据
				if (workflowInstanceModel.getState() == WorkflowInstanceStatus.DRAFT && userId.equals(workflowInstanceModel.getOriginator())) {
					idsForSheet.remove(workflowInstanceModel.getBizObjectId());
				}
			});
			noDeleteIds.addAll(idsForSheet);
			ids.removeAll(idsForSheet);
		}
	}

	/**
	 * 获取查询条件对象
	 *
	 * @param userId
	 * @param queryDataVO   查询数据结果
	 * @param bizQueryModel 列表详细信息
	 * @return BizObjectQueryModel
	 */
	/**
	 * @param userId        用户id
	 * @param queryDataVO   查询数据结果
	 * @param bizQueryModel 列表详细信息
	 * @param isAuthFilter  是否权限查询
	 * @param isOwner       拥有者修改时调用查找权限时用的字段
	 * @returnBizObjectQueryModel
	 */
	protected BizObjectQueryModel getBizObjectQuerys(String userId, QueryDataVO queryDataVO, BizQueryModel bizQueryModel, Boolean isAuthFilter, Boolean isOwner) {
		List<FilterExpression> filterExprs = new ArrayList<>();
		//权限条件
		FilterExpression authFilter = FilterExpression.empty;
		if (isAuthFilter) {

			//是否临时授权
			if (StringUtils.isNotEmpty(queryDataVO.getTempAuthObjectId()) || StringUtils.isNotEmpty(queryDataVO.getTempAuthPropertyCode())) {
				BizFormModel sourceSheet = getBizObjectFacade().getTempAuthSchemaCodes(queryDataVO.getTempAuthSheetId());
				if (sourceSheet == null) {
					authFilter = getAuthFilters(userId, queryDataVO.getSchemaCode(), isOwner);
				} else {
					//跳转过来的源表单的临时授权当前访问的表单  与前端约定保存的表单数据为 SchemaCode_SheetCode
					if (sourceSheet.getTempAuthSchemaCodes().contains(bizQueryModel.getSchemaCode() + "_")) {
						authFilter = getAuthFilters(userId, sourceSheet.getSchemaCode(), isOwner);
					} else {
						authFilter = getAuthFilters(userId, queryDataVO.getSchemaCode(), isOwner);
					}
				}
			} else {
				authFilter = getAuthFilters(userId, queryDataVO.getSchemaCode(), isOwner);
			}
		}
		//生成查询条件
		FilterExpression finalFilterExpr = getFilterList(queryDataVO.getFilters(), bizQueryModel.getQueryConditions(), queryDataVO.isCustomizedQuery());

		//生成选中的列表的查询条件
		FilterExpression checkedFilter = getCheckedFilters(queryDataVO.getObjectIds());

		if (!Objects.equals(authFilter, FilterExpression.empty)) {
			filterExprs.add(authFilter);
		}
		if (!finalFilterExpr.equals(FilterExpression.empty)) {
			filterExprs.add(finalFilterExpr);
		}
		if (!checkedFilter.equals(FilterExpression.empty)) {
			filterExprs.add(checkedFilter);
		}
		this.filterSeqStatus(userId, filterExprs);

		BizObjectQueryModel bizObjectQueryObject = new BizObjectQueryModel();
		FilterExpression filterExprTemplate = FilterExpression.empty;
		if (filterExprs.size() > 1) {
			filterExprTemplate = Q.and(filterExprs);
			if (log.isDebugEnabled()) {
				log.debug("获取的权限相关条件为{}", JSON.toJSONString(filterExprTemplate));
			}
		} else if (filterExprs.size() == 1) {
			filterExprTemplate = filterExprs.get(0);
			if (log.isDebugEnabled()) {
				log.debug("获取的权限相关条件为{}", JSON.toJSONString(filterExprTemplate));
			}
		}

		bizObjectQueryObject.setFilterExpr(filterExprTemplate);
		bizObjectQueryObject.setSchemaCode(bizQueryModel.getSchemaCode());
		bizObjectQueryObject.setClientType(Objects.nonNull(queryDataVO.getMobile()) && queryDataVO.getMobile() ? ClientType.APP : ClientType.PC);
		return bizObjectQueryObject;
	}

	/**
	 * 获取关联查询/反关联查询条件对象
	 *
	 * @param userId        用户id
	 * @param queryDataVO   查询数据结果
	 * @param bizQueryModel 列表详细信息
	 * @return BizObjectQueryModel
	 */
	@Override
	protected BizObjectQueryModel getBizObjectQuery(String userId, QueryDataVO queryDataVO, BizQueryModel bizQueryModel, Boolean isAuthFilter, Boolean isOwner) {
		List<FilterExpression> filterExprs = new ArrayList<>();
		//权限条件
		FilterExpression authFilter = FilterExpression.empty;
		if (isAuthFilter) {
			authFilter = getAuthFilters(userId, queryDataVO.getSchemaCode(), isOwner);
		}
		//生成查询条件
		FilterExpression finalFilterExpr = getFilters(queryDataVO.getFilters(), bizQueryModel.getQueryConditions());

		//生成选中的列表的查询条件
		FilterExpression checkedFilter = getCheckedFilters(queryDataVO.getObjectIds());
		if (!authFilter.equals(FilterExpression.empty)) {
			filterExprs.add(authFilter);
		}
		if (!finalFilterExpr.equals(FilterExpression.empty)) {
			filterExprs.add(finalFilterExpr);
		}
		if (!checkedFilter.equals(FilterExpression.empty)) {
			filterExprs.add(checkedFilter);
		}

		//有流程的数据排除模拟流程的数据 SIMULATIVE；没有流程的保留 workflowInstanceId 为空
		List<String> simulatives = getWorkflowInstanceFacade().findIdListBySchemaCodeAndDataType(queryDataVO.getSchemaCode(), ProcessDataType.SIMULATIVE);
		if (!CollectionUtil.isEmpty(simulatives)) {
			FilterExpression.Or or = Q.or(Q.it(DefaultPropertyType.WORKFLOW_INSTANCE_ID.getCode(), FilterExpression.Op.NotIn, simulatives),
					Q.it(DefaultPropertyType.WORKFLOW_INSTANCE_ID.getCode(), FilterExpression.Op.Eq, null));
			filterExprs.add(or);
		}
		this.filterSeqStatus(userId, filterExprs);

		BizObjectQueryModel bizObjectQueryObject = new BizObjectQueryModel();
		FilterExpression filterExprTemplate = FilterExpression.empty;
		if (filterExprs.size() > 1) {
			filterExprTemplate = Q.and(filterExprs);
			if (log.isDebugEnabled()) {
				log.debug("获取的权限相关条件为{}", JSON.toJSONString(filterExprTemplate));
			}
		} else if (filterExprs.size() == 1) {
			filterExprTemplate = filterExprs.get(0);
			if (log.isDebugEnabled()) {
				log.debug("获取的权限相关条件为{}", JSON.toJSONString(filterExprTemplate));
			}
		}

		bizObjectQueryObject.setFilterExpr(filterExprTemplate);
		bizObjectQueryObject.setSchemaCode(bizQueryModel.getSchemaCode());
		bizObjectQueryObject.setClientType(Objects.nonNull(queryDataVO.getMobile()) && queryDataVO.getMobile() ? ClientType.APP : ClientType.PC);
		return bizObjectQueryObject;
	}

	/**
	 * 不能查看不是自己的草稿
	 *
	 * @param userId
	 * @param filterExprs
	 */
	private void filterSeqStatus(String userId, List<FilterExpression> filterExprs) {
		FilterExpression.And eqDraft = Q.and(Q.it(DefaultPropertyType.CREATER.getCode(), FilterExpression.Op.Eq, userId),
				Q.it(DefaultPropertyType.SEQUENCE_STATUS.getCode(), FilterExpression.Op.Eq, WorkflowInstanceStatus.DRAFT.toString()));
		FilterExpression.Or or = Q.or(eqDraft,
				Q.it(DefaultPropertyType.SEQUENCE_STATUS.getCode(), FilterExpression.Op.NotEq, WorkflowInstanceStatus.DRAFT.toString()));
		filterExprs.add(or);
	}


	private FilterExpression getFilterList(List<FilterVO> filterList, List<BizQueryConditionModel> queryConditions, boolean customizedQuery) {
		if (CollectionUtils.isEmpty(queryConditions) && CollectionUtils.isEmpty(filterList)) {
			return FilterExpression.empty;
		}
		List<FilterExpression> filters = new ArrayList<>();
		//需要处理的可见条件
		List<BizQueryConditionModel> visibleCondition = null;
		//需要处理的隐藏条件=
		List<BizQueryConditionModel> hiddenCondition = null;
		if (CollectionUtils.isNotEmpty(queryConditions)) {
			visibleCondition = queryConditions.stream().filter(condition -> condition.getVisible()).collect(Collectors.toList());
			hiddenCondition = queryConditions.stream().filter(condition -> !condition.getVisible()).collect(Collectors.toList());
		}

		if (!customizedQuery) {
			//生成可见适配条件
			if (CollectionUtils.isNotEmpty(filterList)) {
				if (CollectionUtils.isNotEmpty(visibleCondition)) {
					createVisibleFilters(filterList, visibleCondition, filters);
				}
				if (CollectionUtils.isNotEmpty(hiddenCondition)) {
					createHiddenFilter(filterList, hiddenCondition, filters);
				}
			}

			//可见和隐藏适配条件的编码
			List<String> codeList = new ArrayList<>();
			if (CollectionUtils.isNotEmpty(visibleCondition)) {
				List<String> propertyCodeList = visibleCondition.stream().map(BizQueryConditionModel::getPropertyCode).collect(Collectors.toList());
				codeList.addAll(propertyCodeList);
			}
			if (CollectionUtils.isNotEmpty(hiddenCondition)) {
				List<String> propertyCodeList = hiddenCondition.stream().map(BizQueryConditionModel::getPropertyCode).collect(Collectors.toList());
				codeList.addAll(propertyCodeList);
			}

			for (FilterVO filterVO : filterList) {
				if (filterVO.getOperatorType() != null) {
					FilterExpression.Op op = FilterExpression.Op.Like;
					switch (filterVO.getOperatorType()) {
						case NEQ:
						case IS_NOT_NULL:
							op = FilterExpression.Op.NotEq;
							break;
						case GT:
							op = FilterExpression.Op.Gt;
							break;
						case IT:
							op = FilterExpression.Op.Lt;
							break;
						case GTEQ:
							op = FilterExpression.Op.Gte;
							break;
						case ITEQ:
							op = FilterExpression.Op.Lte;
							break;
						case NOT_OF:
						case NOT_HAVE:
						case NOT_IN:
						case NOT_CONTAINS:
							op = FilterExpression.Op.NotLike;
							break;
						case IS_NULL:
						case EQ:
							op = FilterExpression.Op.Eq;
							break;
						case HAVE:
						case IN:
						case CONTAINS:
						case OF:
							op = FilterExpression.Op.Like;
							break;
						default:
					}
					if (filterVO.getPropertyType() == BizPropertyType.ADDRESS) {
						setAddressPropertyFilter(filters, filterVO, filterVO.getPropertyCode());
					} else if (filterVO.getPropertyType().equals(BizPropertyType.SELECTION)) {
						FilterExpression.Item item = null;
						List<String> value = filterVO.getPropertyValue();
						if (CollectionUtils.isNotEmpty(value)) {
							FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), op, value);
							filters.add(items);
						} else {
							FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), op, value);
							filters.add(items);
						}
					} else if (filterVO.getPropertyType().equals(BizPropertyType.LOGICAL)) {
						FilterExpression.Item item = Q.it(filterVO.getPropertyCode(), op, filterVO.getPropertyValue().get(0));
						filters.add(item);
					} else {
						List<String> propertyValue = filterVO.getPropertyValue();
						if (CollectionUtils.isNotEmpty(propertyValue) && null != filterVO.getOperatorType()) {
							for (String s : propertyValue) {
								FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), op, s);
								filters.add(items);
							}
						} else {
							FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), op, "");
							filters.add(items);
						}
					}
					continue;
				}

				if (DefaultPropertyType.SEQUENCE_STATUS.getCode().equals(filterVO.getPropertyCode())) {
					if (CollectionUtils.isEmpty(filterVO.getPropertyValue())) {
						continue;
					}
					FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), FilterExpression.Op.In, filterVO.getPropertyValue());
					filters.add(items);
				}
				//查询信息是否是配置条件，如果是就无需再操作
				if (CollectionUtils.isEmpty(filterVO.getPropertyValue()) || StringUtils.isBlank(StringUtils.strip(filterVO.getPropertyValue().toString(), "[]"))) {
					continue;
				}
				if (CollectionUtils.isNotEmpty(codeList)) {
					if (codeList.contains(filterVO.getPropertyCode())) {
						continue;
					}
					FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Like, filterVO.getPropertyValue());
					filters.add(items);
				} else {
					FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Like, filterVO.getPropertyValue());
					filters.add(items);
				}
			}
		} else {
			for (FilterVO filterVO : filterList) {
				FilterExpression.Op op = FilterExpression.Op.Like;
				if (filterVO.getOp() != null) {
					switch (filterVO.getOp()) {
						case Eq:
							op = FilterExpression.Op.Eq;
							break;
						case NotEq:
							op = FilterExpression.Op.NotEq;
							break;
						case Like:
							op = FilterExpression.Op.Like;
							break;
						case NotLike:
							op = FilterExpression.Op.NotLike;
							break;
						case Gt:
							op = FilterExpression.Op.Gt;
							break;
						case Lt:
							op = FilterExpression.Op.Lt;
							break;
					}
				}
				if (filterVO.getPropertyType() == BizPropertyType.ADDRESS) {
					setAddressPropertyFilter(filters, filterVO, filterVO.getPropertyCode());
				} else {
					List<String> propertyValue = filterVO.getPropertyValue();
					if (CollectionUtils.isNotEmpty(propertyValue)) {
						for (String s : propertyValue) {
							FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), op, s);
							filters.add(items);
						}
					} else {
						FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), op, null);
						filters.add(items);
					}
				}
			}
		}

		if (CollectionUtils.isEmpty(filters)) {
			return FilterExpression.empty;
		}
		if (filters.size() == 1) {
			return filters.get(0);
		}
		return Q.and(filters);
	}


	/**
	 * 关联查询和反关联生成查询条件
	 *
	 * @param filterList      查询条件
	 * @param queryConditions 查询条件
	 * @return FilterExpr
	 */
	private FilterExpression getFilters(List<FilterVO> filterList, List<BizQueryConditionModel> queryConditions) {
		if (CollectionUtils.isEmpty(queryConditions) && CollectionUtils.isEmpty(filterList)) {
			return FilterExpression.empty;
		}
		List<FilterExpression> filters = new ArrayList<>();
		//需要处理的可见条件
		List<BizQueryConditionModel> visibleCondition = null;
		//需要处理的隐藏条件=
		List<BizQueryConditionModel> hiddenCondition = null;
		if (CollectionUtils.isNotEmpty(queryConditions)) {
			visibleCondition = queryConditions.stream().filter(condition -> condition.getVisible()).collect(Collectors.toList());
			hiddenCondition = queryConditions.stream().filter(condition -> !condition.getVisible()).collect(Collectors.toList());
		}

		//生成可见适配条件
		if (CollectionUtils.isNotEmpty(filterList)) {
			if (CollectionUtils.isEmpty(visibleCondition) && CollectionUtils.isEmpty(hiddenCondition)) {
				createVisibleFilter(filterList, visibleCondition, filters);
			} else {
				if (CollectionUtils.isNotEmpty(visibleCondition)) {
					createVisibleFilter(filterList, visibleCondition, filters);
				}
				if (CollectionUtils.isNotEmpty(hiddenCondition)) {
					createHiddenFilter(filterList, hiddenCondition, filters);
				}
			}
		}
		if (CollectionUtils.isEmpty(filters)) {
			return FilterExpression.empty;
		}
		if (filters.size() == 1) {
			return filters.get(0);
		}
		return Q.and(filters);
	}

	/**
	 * 根据选项构建正则表达式查询条件
	 *
	 * @param propertyValue
	 * @return
	 */
	private String generateRegex(List<String> propertyValue) {
		StringBuilder sb = new StringBuilder();
		for (String value : propertyValue) {
			sb.append("(").append(value).append(")");
		}
		return String.format(DEFAULT_REGEX, sb.toString(), propertyValue.size() - 1, sb.toString());
	}

	/**
	 * 排列组合的结果集
	 *
	 * @param value
	 * @return
	 */
	public List<String> getPropertyValue(List<String> value) {

		List<String> result = new ArrayList<>();
		for (int i = 0; i < value.size(); i++) {
			List<String> medium = new ArrayList<>();
			arrangementSort(value, Arrays.asList(new String[i + 1]), 0, medium);
			result.addAll(medium);
		}
		return result;
	}

	/**
	 * 通过递归的方式罗列出所有的排列结果
	 *
	 * @param value：初始数组
	 * @param init：排列数组初始状态
	 * @param resultIndex：比较的起始索引
	 */
	public static void arrangementSort(List<String> value, List<String> init, int resultIndex, List<String> medium) {
		int result_length = init.size();
		if (resultIndex >= result_length) {
			if (init.size() > 1) {
				String join = Joiner.on(";").skipNulls().join(init);
				medium.add(join);
			} else {
				medium.addAll(init);
			}
			return;
		}
		for (int i = 0; i < value.size(); i++) {
			// 判断待选的数是否存在于排列的结果中
			boolean exist = false;
			for (int j = 0; j < resultIndex; j++) {
				if (Objects.equals(value.get(i), init.get(j))) {  // 若已存在，则不能重复选
					exist = true;
					break;
				}
			}
			if (!exist) {  // 若不存在，则可以选择
				String s = value.get(i);
				init.set(resultIndex, s);
				arrangementSort(value, init, resultIndex + 1, medium);
			}
		}
	}

	/**
	 * 生成隐藏过滤条件
	 *
	 * @param hiddenCondition 查询条件
	 * @param filters         过滤
	 */
	private void createHiddenFilter(List<FilterVO> filterVOs, List<BizQueryConditionModel> hiddenCondition, List<FilterExpression> filters) {
		//如果表单配置的过滤条件无在这里过滤
		filterVOs = filterVOs.stream().filter(filterVO -> Objects.isNull(filterVO.getOperatorType())).collect(Collectors.toList());
		for (BizQueryConditionModel condition : hiddenCondition) {
			//oracle数据库下 默认值为null，生成过滤条件异常。
			String defaultValue = StringUtils.isBlank(condition.getDefaultValue()) ? "" : condition.getDefaultValue();
			List<String> properValue = Arrays.asList(defaultValue.split(";"));
			FilterExpression.Item item = null;
			if (condition.getPropertyType().equals(BizPropertyType.SELECTION)) {
				filterVOs = filterVOs.stream().filter(t -> Objects.equals(t.getPropertyType(), BizPropertyType.SELECTION)).collect(Collectors.toList());

				List<String> idsP = Lists.newArrayList();
				List<String> idsDpt = Lists.newArrayList();
				List<String> idsSelection = Lists.newArrayList();
				filterVOs.forEach(t -> {
					List<String> values = t.getPropertyValue();
					if (CollectionUtils.isEmpty(values)) {
						return;
					}
					if (Objects.equals(t.getPropertyCode(), DefaultPropertyType.CREATER.getCode()) || Objects.equals(t.getPropertyCode(), DefaultPropertyType.OWNER.getCode())) {
						idsP.addAll(values);
					} else if (Objects.equals(t.getPropertyCode(), DefaultPropertyType.CREATED_DEPT_ID.getCode()) || Objects.equals(t.getPropertyCode(), DefaultPropertyType.OWNER_DEPT_ID.getCode())) {
						idsDpt.addAll(values);
					}
					if (CollectionUtils.isNotEmpty(values)) {
						idsSelection.addAll(values);
					}
				});
				List<String> defaults = filterVOs.get(0).getDefaultProperties();
				if (Objects.equals(condition.getDefaultValue(), "1")) {
					//本人
					if (defaults.contains(condition.getPropertyCode())) {
						item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, idsP);
						if (CollectionUtils.isNotEmpty(idsP)) {
							filters.add(item);
						}
					} else {
						List<FilterExpression> items = Lists.newArrayList();
						if (CollectionUtils.isNotEmpty(idsSelection)) {
							for (String id : idsSelection) {
								items.add(Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, id));
							}
							if (items.size() == 1) {
								filters.add(items.get(0));
							} else {
								filters.add(Q.or(items));
							}
						}
					}
				} else if (Objects.equals(condition.getDefaultValue(), "2")) {
					//本部门
					if (defaults.contains(condition.getPropertyCode())) {
						item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, idsDpt);
						if (CollectionUtils.isNotEmpty(idsDpt)) {
							filters.add(item);
						}
					} else {
						List<FilterExpression> items = Lists.newArrayList();
						for (String id : idsSelection) {
							items.add(Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, id));
						}
						//对条件判空
						if (CollectionUtils.isNotEmpty(items)) {
							if (items.size() == 1) {
								filters.add(items.get(0));
							} else {
								filters.add(Q.or(items));
							}
						}
					}
				}
				continue;
			}

			if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.CHECKBOX)) {
				item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, properValue);
				if (CollectionUtils.isNotEmpty(properValue)) {
					filters.add(item);
				}
				continue;
			}
			if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.SELECT)) {
				//多选精确查询

				if (CollectionUtils.isNotEmpty(properValue) && properValue.size() > 1) {
					String regex = generateRegex(properValue);
					FilterExpression.Item it = Q.it(condition.getPropertyCode(), FilterExpression.Op.Reg, regex);
					filters.add(it);
					continue;
				} else if (CollectionUtils.isEmpty(properValue)) {
					continue;
				} else if (CollectionUtils.isNotEmpty(properValue) && properValue.size() == 1) {
					String s = properValue.get(0);
					if (StringUtils.isEmpty(s)) {
						continue;
					}
					item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, properValue);
					filters.add(item);
					continue;
				}
			}
			if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.RANGE) || condition.getPropertyType().equals(BizPropertyType.NUMERICAL) || condition.getPropertyType().equals(BizPropertyType.DATE)) {
				//拿到传入的条件
				FilterVO filter = null;
				if (CollectionUtils.isNotEmpty(filterVOs)) {
					List<FilterVO> collect = filterVOs.stream().filter(filterVO -> Objects.equals(filterVO.getPropertyCode(), condition.getPropertyCode())).collect(Collectors.toList());
					if (CollectionUtils.isNotEmpty(collect)) {
						filter = collect.get(0);
					}
				}
				createScopeFilter(condition, filter, filters, Boolean.TRUE);
				continue;
			}
			if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.INPUT)) {
				if (condition.getPropertyType() == BizPropertyType.ADDRESS) {
					List<FilterVO> collect = filterVOs.stream().filter(f -> condition.getPropertyCode().equals(f.getPropertyCode())).collect(Collectors.toList());
					if (CollectionUtils.isNotEmpty(collect) && CollectionUtils.isNotEmpty(collect.get(0).getPropertyValue())) {
						String address = collect.get(0).getPropertyValue().get(0);
						Map<String, String> addressMap = JSON.parseObject(address, new TypeReference<Map<String, String>>() {
						});
						String provinceAdcode = addressMap.get("provinceAdcode");
						String cityAdcode = addressMap.get("cityAdcode");
						String districtAdcode = addressMap.get("districtName");
						if (StringUtils.isNotEmpty(provinceAdcode)) {
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, provinceAdcode);
							filters.add(item);
						}
						if (StringUtils.isNotEmpty(cityAdcode)) {
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, cityAdcode);
							filters.add(item);
						}
						if (StringUtils.isNotEmpty(districtAdcode)) {
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, districtAdcode);
							filters.add(item);
						}
					}
				} else if (condition.getPropertyType() == BizPropertyType.LOGICAL) {
					List<FilterVO> collect = filterVOs.stream().filter(f -> condition.getPropertyCode().equals(f.getPropertyCode())).collect(Collectors.toList());
					if (CollectionUtils.isNotEmpty(collect) && CollectionUtils.isNotEmpty(collect.get(0).getPropertyValue())) {
						String logic = collect.get(0).getPropertyValue().get(0);
						if (StringUtils.isNotEmpty(logic)) {
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, logic);
							filters.add(item);
						}
					}
				} else {
					List<FilterVO> collect = filterVOs.stream().filter(filterVO -> Objects.equals(filterVO.getPropertyCode().toString(), condition.getPropertyCode().toString())).collect(Collectors.toList());
					if (CollectionUtils.isNotEmpty(collect)) {
						List<String> propertyValue = collect.get(0).getPropertyValue();
						if (CollectionUtils.isNotEmpty(propertyValue)) {
							String s = collect.get(0).getPropertyValue().get(0);
							if (StringUtils.isNotEmpty(s)) {
								item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, s);
								filters.add(item);
							}
						}
					}

				}
				continue;
			}
			List<FilterVO> collect = filterVOs.stream().filter(filterVO -> Objects.equals(filterVO.getPropertyCode(), condition.getPropertyCode())).collect(Collectors.toList());
			item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, collect.get(0).getPropertyValue().get(0));
			filters.add(item);
			continue;
		}

	}

	private void createVisibleFilters(List<FilterVO> filterVOs, List<BizQueryConditionModel> visibleCondition, List<FilterExpression> filters) {
		//如果表单配置的过滤条件无在这里过滤
		filterVOs = filterVOs.stream().filter(filterVO -> Objects.isNull(filterVO.getOperatorType())).collect(Collectors.toList());
		for (FilterVO filterVO : filterVOs) {
			boolean machAble = false;
			if (BizPropertyType.WORK_SHEET.equals(filterVO.getPropertyType())) {
				if (CollectionUtils.isEmpty(filterVO.getPropertyValue())) {
					continue;
				}
				FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValue().get(0));
				filters.add(items);
			}
			if (CollectionUtils.isNotEmpty(visibleCondition)) {
				for (BizQueryConditionModel condition : visibleCondition) {
					FilterExpression.Item item = null;
					if (filterVO.getPropertyCode().equals(condition.getPropertyCode())) {
						machAble = true;
						if (CollectionUtils.isEmpty(filterVO.getPropertyValue())) {
							continue;
						}
						if (condition.getPropertyType().equals(BizPropertyType.SELECTION)) {
							List<String> defaults = filterVO.getDefaultProperties();
							if (defaults.contains(filterVO.getPropertyCode()) &&
									(DefaultPropertyType.OWNER_DEPT_ID.getCode().equals(filterVO.getPropertyCode()) ||
											DefaultPropertyType.CREATED_DEPT_ID.getCode().equals(filterVO.getPropertyCode()))) {
								//创建人部门过滤权限
								List<String> departmentIds = Lists.newArrayList();
								for (String deptId : filterVO.getPropertyValue()) {
									List<String> deptIds = Lists.newArrayList();
									departmentIds.add(deptId);
									List<DepartmentModel> departmentModels = getOrganizationFacade().getDepartmentsChildList(departmentIds, true);
									if (CollectionUtils.isNotEmpty(departmentModels)) {
										departmentModels.stream().forEach(departmentModel -> {
											deptIds.add(departmentModel.getId());
										});
										deptIds.add(deptId);
										departmentIds.addAll(deptIds);
									} else {
										departmentIds.add(deptId);
									}
								}
								item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, departmentIds);
								if (CollectionUtils.isNotEmpty(departmentIds)) {
									filters.add(item);
								}
								break;
							}

							if (defaults.contains(filterVO.getPropertyCode())) {
								item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, filterVO.getPropertyValue());
								if (CollectionUtils.isNotEmpty(filterVO.getPropertyValue())) {
									filters.add(item);
								}
								break;
							}
							List<FilterExpression> filterTemplates = new ArrayList<>();
							for (String s : filterVO.getPropertyValue()) {
								filterTemplates.add(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Like, s));
							}
							if (CollectionUtils.isNotEmpty(filterTemplates)) {
								if (filterTemplates.size() == 1) {
									filters.add(filterTemplates.get(0));
								} else {
									filters.add(Q.or(filterTemplates));
								}
							}
							break;
						}
						if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.CHECKBOX)) {
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, filterVO.getPropertyValue());
							filters.add(item);
							break;
						}
						if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.SELECT)) {
							//修改  多选精确查询
							List<String> propertyValue = filterVO.getPropertyValue();
							if (CollectionUtils.isNotEmpty(propertyValue) && propertyValue.size() > 1) {
								String regex = generateRegex(propertyValue);
								FilterExpression.Item it = Q.it(condition.getPropertyCode(), FilterExpression.Op.Reg, regex);
								filters.add(it);
								break;
							}
							//修改 修改  多选精确查询
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValue());
							filters.add(item);
							break;
						}
						if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.RANGE) || condition.getPropertyType().equals(BizPropertyType.NUMERICAL) || condition.getPropertyType().equals(BizPropertyType.DATE)) {
							createScopeFilter(condition, filterVO, filters, false);
							break;
						}
						if (condition.getPropertyType().equals(BizPropertyType.LOGICAL)) {
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValue().get(0));
							filters.add(item);
							break;
						}
						if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.INPUT)) {
							/*
							 * 地址控件类型查询条件，根据编码查询
							 * 格式:
							 *    省
							 *    省-市
							 *    省-市-区
							 */
							setAddressPropertyFilter(filters, filterVO, condition.getPropertyCode());
							break;
						}
						item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValue().get(0));
						filters.add(item);
						break;
					}
				}
			}
		}
	}

	/**
	 * 设置地址控件属性过滤值
	 *
	 * @param filters
	 * @param filterVO
	 * @param propertyCode
	 */
	private void setAddressPropertyFilter(List<FilterExpression> filters, FilterVO filterVO, String propertyCode) {
		FilterExpression.Item item;
		if (filterVO.getPropertyType() == BizPropertyType.ADDRESS) {
			String address = filterVO.getPropertyValue().get(0);
			Map<String, String> addressMap = JSON.parseObject(address, new TypeReference<Map<String, String>>() {
			});
			String provinceAdcode = addressMap.get("provinceAdcode");
			String cityAdcode = addressMap.get("cityAdcode");
			String districtAdcode = addressMap.get("districtName");
			if (StringUtils.isNotEmpty(provinceAdcode)) {
				item = Q.it(propertyCode, FilterExpression.Op.Like, provinceAdcode);
				filters.add(item);
			}
			if (StringUtils.isNotEmpty(cityAdcode)) {
				item = Q.it(propertyCode, FilterExpression.Op.Like, cityAdcode);
				filters.add(item);
			}
			if (StringUtils.isNotEmpty(districtAdcode)) {
				item = Q.it(propertyCode, FilterExpression.Op.Like, districtAdcode);
				filters.add(item);
			}
		} else {
			if (StringUtils.isNotBlank(filterVO.getPropertyValue().get(0))) {
				item = Q.it(propertyCode, FilterExpression.Op.Like, filterVO.getPropertyValue().get(0));
				filters.add(item);
			}
		}
	}


	/**
	 * 生成关联查询/反关联查询可见过滤条件条件
	 *
	 * @param filterVOs        查询条件
	 * @param visibleCondition 查询条件
	 * @param filters          过滤
	 */
	private void createVisibleFilter(List<FilterVO> filterVOs, List<BizQueryConditionModel> visibleCondition, List<FilterExpression> filters) {
		for (FilterVO filterVO : filterVOs) {
			boolean machAble = false;
			if (BizPropertyType.WORK_SHEET.equals(filterVO.getPropertyType())) {
				if (CollectionUtils.isEmpty(filterVO.getPropertyValue())) {
					continue;
				}
				FilterExpression.Item items = Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValue().get(0));
				filters.add(items);
			}
			if (CollectionUtils.isNotEmpty(visibleCondition)) {
				for (BizQueryConditionModel condition : visibleCondition) {
					FilterExpression.Item item = null;
					if (filterVO.getPropertyCode().equals(condition.getPropertyCode())) {
						machAble = true;
						if (CollectionUtils.isEmpty(filterVO.getPropertyValue())) {
							continue;
						}
						if (condition.getPropertyType().equals(BizPropertyType.SELECTION)) {
							List<String> defaults = filterVO.getDefaultProperties();
							if (defaults.contains(filterVO.getPropertyCode()) &&
									(DefaultPropertyType.OWNER_DEPT_ID.getCode().equals(filterVO.getPropertyCode()) ||
											DefaultPropertyType.CREATED_DEPT_ID.getCode().equals(filterVO.getPropertyCode()))) {
								//创建人部门过滤权限
								List<String> departmentIds = Lists.newArrayList();
								for (String deptId : filterVO.getPropertyValue()) {
									List<String> deptIds = Lists.newArrayList();
									List<DepartmentModel> departmentModels = getOrganizationFacade().getDepartmentsChildList(departmentIds, true);
									if (CollectionUtils.isNotEmpty(departmentModels)) {
										departmentModels.stream().forEach(departmentModel -> {
											deptIds.add(departmentModel.getId());
										});
										deptIds.add(deptId);
										departmentIds.addAll(deptIds);
									} else {
										departmentIds.add(deptId);
									}
								}
								item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, departmentIds);
								if (CollectionUtils.isNotEmpty(departmentIds)) {
									filters.add(item);
								}
								break;
							}

							if (defaults.contains(filterVO.getPropertyCode())) {
								item = Q.it(condition.getPropertyCode(), FilterExpression.Op.In, filterVO.getPropertyValue());
								if (CollectionUtils.isNotEmpty(filterVO.getPropertyValue())) {
									filters.add(item);
								}
								break;
							}
							List<FilterExpression> filterTemplates = new ArrayList<>();
							for (String s : filterVO.getPropertyValue()) {
								filterTemplates.add(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Like, s));
							}
							if (CollectionUtils.isNotEmpty(filterTemplates)) {
								if (filterTemplates.size() == 1) {
									filters.add(filterTemplates.get(0));
								} else {
									filters.add(Q.or(filterTemplates));
								}
							}
							break;
						}
						if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.CHECKBOX)) {
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Like, filterVO.getPropertyValue());
							filters.add(item);
							break;
						}
						if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.SELECT)) {
							//修改  多选精确查询
							List<String> propertyValue = filterVO.getPropertyValue();
							if (CollectionUtils.isNotEmpty(propertyValue) && propertyValue.size() > 1) {
								String regex = generateRegex(propertyValue);
								FilterExpression.Item it = Q.it(condition.getPropertyCode(), FilterExpression.Op.Reg, regex);
								filters.add(it);
								break;
							}
							//修改 修改  多选精确查询
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValue());
							filters.add(item);
							break;
						}
						if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.RANGE) || condition.getPropertyType().equals(BizPropertyType.NUMERICAL) || condition.getPropertyType().equals(BizPropertyType.DATE)) {
							createScopeFilter(condition, filterVO, filters, false);
							break;
						}
						if (condition.getPropertyType().equals(BizPropertyType.LOGICAL)) {
							item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValue().get(0));
							filters.add(item);
							break;
						}
						if (condition.getDisplayType() != null && condition.getDisplayType().equals(DisplayType.INPUT)) {
							/*
							 * 地址控件类型查询条件，根据编码查询
							 * 格式:
							 *    省
							 *    省-市
							 *    省-市-区
							 */
							setAddressPropertyFilter(filters, filterVO, condition.getPropertyCode());
							break;
						}
						item = Q.it(condition.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValue().get(0));
						filters.add(item);
						break;
					}
				}
			}

			if (!machAble) {
				if (filterVO.getPropertyCode().equals(DefaultPropertyType.SEQUENCE_STATUS.getCode())) {
					if (CollectionUtils.isNotEmpty(filterVO.getPropertyValue())) {
						filters.add(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.In, filterVO.getPropertyValue()));
					}
					continue;
				}
				List<String> defaultCodes = filterVO.getDefaultProperties();
				if (defaultCodes.contains(filterVO.getPropertyCode())) {
					if (filterVO.getPropertyType() == BizPropertyType.SHORT_TEXT && CollectionUtils.isNotEmpty(filterVO.getPropertyValue())) {
						filters.add(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Like, filterVO.getPropertyValue().get(0)));
					} else if (filterVO.getPropertyType() == BizPropertyType.ID && CollectionUtils.isNotEmpty(filterVO.getPropertyValue())) {
						filters.add(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.In, filterVO.getPropertyValue()));
					} else {
						if (CollectionUtils.isNotEmpty(filterVO.getPropertyValue())) {
							filters.add(Q.it(filterVO.getPropertyCode(), FilterExpression.Op.Eq, filterVO.getPropertyValue().get(0)));
						}
					}
					continue;
				}
				if (log.isDebugEnabled()) {
					log.debug("查询条件不匹配: {}", filterVO.getPropertyCode());
				}
			}
		}
	}

	/**
	 * 获取范围查询条件
	 *
	 * @param condition 查询条件
	 * @param filterVO  查询条件
	 * @param filters   过滤
	 * @param isDefault 是否默认
	 */
	private void createScopeFilter(BizQueryConditionModel condition, FilterVO filterVO, List<FilterExpression> filters, Boolean isDefault) {
		//默认值情况
		FilterExpression.Item itemStart = null;
		FilterExpression.Item itemEnd = null;
		List<String> values = filterVO == null ? null : filterVO.getPropertyValue();
		Object startValue = null;
		Object endValue = null;
		if (CollectionUtils.isEmpty(values)) {
			startValue = isDefault ? (condition.getStartValue() == null ? null : ("".equals(condition.getStartValue()) ? null : condition.getStartValue())) : (values == null ? null : values.get(0));
			endValue = isDefault ? (condition.getEndValue() == null ? null : ("".equals(condition.getEndValue()) ? null : condition.getEndValue())) : (values == null ? null : values.get(1));
		} else {
			if (values.size() == 1) {
				startValue = isDefault ? (condition.getStartValue() == null ? null : ("".equals(condition.getStartValue()) ? null : condition.getStartValue())) : (values == null ? null : values.get(0));
				endValue = isDefault ? (condition.getEndValue() == null ? null : ("".equals(condition.getEndValue()) ? null : condition.getEndValue())) : (values == null ? null : values.get(0));
			} else if (values.size() == 2) {
				if (isDefault && (!condition.getDateType().equals(0))) {
					startValue = values == null ? null : values.get(0);
					endValue = values == null ? null : values.get(1);
				} else if (!isDefault) {
					startValue = values == null ? null : values.get(0);
					endValue = values == null ? null : values.get(1);
				} else if (isDefault && condition.getDateType().equals(0)) {
					startValue = condition.getStartValue() == null ? null : ("".equals(condition.getStartValue()) ? null : condition.getStartValue());
					endValue = condition.getEndValue() == null ? null : ("".equals(condition.getEndValue()) ? null : condition.getEndValue());
				}

			}
		}

		if (isDefault && condition.getPropertyType() == BizPropertyType.DATE) {
			List<String> list = parseHiddrenDate(startValue, endValue);
			if (CollectionUtils.isNotEmpty(list)) {
				startValue = list.get(0);
				endValue = list.get(1);
			}
		}
		if (null != startValue) {
			itemStart = Q.it(condition.getPropertyCode(), FilterExpression.Op.Gte, startValue);
		}
		if (null != endValue) {
			itemEnd = Q.it(condition.getPropertyCode(), FilterExpression.Op.Lte, endValue);
		}
		if (itemStart != null && itemEnd != null) {
			FilterExpression.And and = Q.and(itemStart, itemEnd);
			filters.add(and);
			return;
		}
		if (itemStart == null && itemEnd == null) {
			return;
		}
		filters.add(itemStart == null ? itemEnd : itemStart);
	}

	private List<String> parseHiddrenDate(Object startValue, Object endValue) {
		if (null != startValue && null != endValue) {
			List<Object> list = new ArrayList<>();
			list.add(startValue);
			list.add(endValue);
			String join = Joiner.on(";").skipNulls().join(list);
			String value = PropertyValidateHelper.parseDate(join);
			List<String> strings = new ArrayList<>(Arrays.asList(value.split(";")));
			return strings;
		}
		return null;
	}

	//控件匹配与否信息
	//@Param T 控件值，不同控件类型不一样
	class CompMatchInfo<T> {
		private T value;//控件显示值
		private Boolean marked;//控件标红与否

		public CompMatchInfo(T value, Boolean marked) {
			this.value = value;
			this.marked = marked;
		}

		public T getValue() {
			return value;
		}

		public void setValue(T value) {
			this.value = value;
		}

		public Boolean getMarked() {
			return marked;
		}

		public void setMarked(Boolean marked) {
			this.marked = marked;
		}
	}

	static class CompProperty {
		private String key;
		private Integer type;
		private Integer width;// "width":150,
		private String parentKey;//       "parentKey":"Sheet1604541828261"
		private Option options;//

		static class Option {
			private String name;//"":"省份",
			private String name_i18n;
			private Boolean visible;//      "":true,
			private String style;//      "style":"",
			private String tips;//        "tips":"",
			private String dataItemName;    //  "":"",
			private String displayFormula;//      "":"",
			private String onChange;  //   "":"",
			private String requiredFormula;//     "":"",
			private Boolean readonlyFormula;//       "":false,
			private String defaultValue;//   "":"河南",
			private String options;//    "options":"河南;河北",
			private String widgetType;//    "widgetType":"",
			private Boolean displayEmpty;//   "displayEmpty":true,
			private String emptyValue;//    "emptyValue":"请选择",
			private Boolean multi;//   "multi":false,
			private Integer width; //    "width":150

			public String getName() {
				return name;
			}

			public void setName(String name) {
				this.name = name;
			}

			public String getName_i18n() {
				return name_i18n;
			}

			public void setName_i18n(String name_i18n) {
				this.name_i18n = name_i18n;
			}

			public Boolean getVisible() {
				return visible;
			}

			public void setVisible(Boolean visible) {
				this.visible = visible;
			}

			public String getStyle() {
				return style;
			}

			public void setStyle(String style) {
				this.style = style;
			}

			public String getTips() {
				return tips;
			}

			public void setTips(String tips) {
				this.tips = tips;
			}

			public String getDataItemName() {
				return dataItemName;
			}

			public void setDataItemName(String dataItemName) {
				this.dataItemName = dataItemName;
			}

			public String getDisplayFormula() {
				return displayFormula;
			}

			public void setDisplayFormula(String displayFormula) {
				this.displayFormula = displayFormula;
			}

			public String getOnChange() {
				return onChange;
			}

			public void setOnChange(String onChange) {
				this.onChange = onChange;
			}

			public String getRequiredFormula() {
				return requiredFormula;
			}

			public void setRequiredFormula(String requiredFormula) {
				this.requiredFormula = requiredFormula;
			}

			public Boolean getReadonlyFormula() {
				return readonlyFormula;
			}

			public void setReadonlyFormula(Boolean readonlyFormula) {
				this.readonlyFormula = readonlyFormula;
			}

			public String getDefaultValue() {
				return defaultValue;
			}

			public void setDefaultValue(String defaultValue) {
				this.defaultValue = defaultValue;
			}

			public String getOptions() {
				return options;
			}

			public void setOptions(String options) {
				this.options = options;
			}

			public String getWidgetType() {
				return widgetType;
			}

			public void setWidgetType(String widgetType) {
				this.widgetType = widgetType;
			}

			public Boolean getDisplayEmpty() {
				return displayEmpty;
			}

			public void setDisplayEmpty(Boolean displayEmpty) {
				this.displayEmpty = displayEmpty;
			}

			public String getEmptyValue() {
				return emptyValue;
			}

			public void setEmptyValue(String emptyValue) {
				this.emptyValue = emptyValue;
			}

			public Boolean getMulti() {
				return multi;
			}

			public void setMulti(Boolean multi) {
				this.multi = multi;
			}

			public Integer getWidth() {
				return width;
			}

			public void setWidth(Integer width) {
				this.width = width;
			}
		}

		public String getKey() {
			return key;
		}

		public void setKey(String key) {
			this.key = key;
		}

		public Integer getType() {
			return type;
		}

		public void setType(Integer type) {
			this.type = type;
		}

		public Integer getWidth() {
			return width;
		}

		public void setWidth(Integer width) {
			this.width = width;
		}

		public String getParentKey() {
			return parentKey;
		}

		public void setParentKey(String parentKey) {
			this.parentKey = parentKey;
		}

		public Option getOptions() {
			return options;
		}

		public void setOptions(Option options) {
			this.options = options;
		}
	}

	private class GetBizQueryOptions {
		private BizPropertyModel bizProperty;
		private Map<String, Object> multWorkMap;
		private BizObjectQueryModel.Options options;
		private List<String> queryCodes;

		public GetBizQueryOptions(BizPropertyModel bizProperty, Map<String, Object> multWorkMap) {
			this.bizProperty = bizProperty;
			this.multWorkMap = multWorkMap;
		}

		public BizObjectQueryModel.Options getOptions() {
			return options;
		}

		public List<String> getQueryCodes() {
			return queryCodes;
		}

		public GetBizQueryOptions invoke() {
			options = new BizObjectQueryModel.Options();
			queryCodes = Lists.newArrayList();
			queryCodes.add("id");
			if (Objects.nonNull(multWorkMap.get(bizProperty.getCode() + "_mappingKeys"))) {
				String mappingKeys = (String) multWorkMap.get(bizProperty.getCode() + "_mappingKeys");

				if (StringUtils.isNotEmpty(mappingKeys)) {
					String mappingKeyStrs[] = mappingKeys.split(";");
					for (String mappingKey : mappingKeyStrs) {
						queryCodes.add(mappingKey);
					}
				}
			}
			options.setCustomDisplayColumns(queryCodes);
			options.setQueryDisplayType(QueryDisplayType.APPEND);
			return this;
		}
	}

	@Override
	@ApiOperation(value = "检查删除数据接口")
	@ApiImplicitParam(name = "params", value = "{\n" +
			"\"ids\":[\"id1\",\"id2\"],\n" +
			"\"schemaCode\":\"模型编码\"\n" +
			"}", required = true, dataType = "Map")
	@PostMapping("/checkForRemoveBizObject")
	public ResponseResult<List<CheckResultForRemoveBizObject>> checkForRemoveBizObject(@RequestBody Map<String, Object> params) {
		List<String> ids = org.apache.commons.collections.MapUtils.isNotEmpty(params) ? (List<String>) params.get("ids") : null;
		String schemaCode = StringUtils.isNotEmpty(params.get("schemaCode").toString()) ? params.get("schemaCode").toString() : null;
		validateParams(ids, schemaCode);
		//校验其他表单是否有关联
		Map<String, List<String>> deleteIdsMap = atsService.validateSchemaCode(ids, schemaCode);
		List<String> deleteIds = deleteIdsMap.get("returnIds");
		List<String> notReturnIds = deleteIdsMap.get("notReturnIds");
		String userId = this.getUserId();
		//过滤有权限删除的数据
		List<String> noDeleteIds = Lists.newArrayList();
		disposeDeletePermissions(userId, schemaCode, ids, noDeleteIds);
		if (CollectionUtils.isNotEmpty(ids) || CollectionUtils.isNotEmpty(noDeleteIds)) {
			List<CheckResultForRemoveBizObject> data = getBizObjectFacade().checkForRemoveBizObject(schemaCode, ids, noDeleteIds);
			for (CheckResultForRemoveBizObject datum : data) {
				if(datum.getResultCode().equals(1004L)){
					List<String> objectIds = datum.getObjectIds();
					if(CollectionUtils.isEmpty(objectIds)){
						objectIds.addAll(notReturnIds);
					}else{
						List<String> conIds = new ArrayList<>();
						for (String objectId : objectIds) {
							if(!notReturnIds.contains(objectId)){
								conIds.add(objectId);
							}
						}
						conIds.addAll(notReturnIds);
						objectIds.clear();
						objectIds.addAll(conIds);
					}
				}else if(datum.getResultCode().equals(1000L)){
					List<String> objectIds = datum.getObjectIds();
					List<String> conIds = new ArrayList<>();
					for (String objectId : objectIds) {
						if(!notReturnIds.contains(objectId)){
							conIds.add(objectId);
						}
					}
					objectIds.clear();
					objectIds.addAll(conIds);
				}
			}
			return this.getOkResponseResult(data, "删除数据检查成功");
		}
		return this.getErrResponseResult(null, -1L, "没有可被删除的数据");
	}

	private void validateParams(List<String> ids, String schemaCode) {
		if (CollectionUtils.isEmpty(ids)) {
			throw new PortalException(ResultEnum.ILLEGAL_PARAMETER_ERR.getErrCode(), "id不能为空");
		}
		if (StringUtils.isEmpty(schemaCode)) {
			throw new PortalException(ResultEnum.ILLEGAL_PARAMETER_ERR.getErrCode(), "模型编码不能为空");
		}
	}

	@Override
	@ApiOperation(value = "列表数据删除接口")
	@ApiImplicitParam(name = "params", value = "{\n" +
			"\"ids\":[\"id1\",\"id2\"],\n" +
			"\"schemaCode\":\"模型编码\"\n" +
			"}", required = true, dataType = "Map")
	@DeleteMapping("/delete_data")
	public ResponseResult<Map<String, Object>> deleteData(@RequestBody Map<String, Object> params) {
		List<String> ids = org.apache.commons.collections.MapUtils.isNotEmpty(params) && params.get("ids") != null ? (List<String>) params.get("ids") : Collections.EMPTY_LIST;
		String schemaCode = StringUtils.isNotEmpty(params.get("schemaCode").toString()) ? params.get("schemaCode").toString() : null;
		//校验其他表单是否有关联
		validateParams(ids, schemaCode);
		Map<String, List<String>> deleteIdsMap = atsService.validateSchemaCode(ids, schemaCode);
		List<String> deleteIds = deleteIdsMap.get("returnIds");
		String userId = this.getUserId();

		int allCount = deleteIds.size();
		//过滤有权限删除的数据
		// TODO  noDeleteIds ？？？
		List<String> noDeleteIds = Lists.newArrayList();
		disposeDeletePermissions(userId, schemaCode, deleteIds, noDeleteIds);
		int filterCount = 0;
		Map<String, Object> map = new HashMap<>();
		if (CollectionUtils.isNotEmpty(deleteIds)) {
			filterCount = deleteIds.size();
			getBizObjectFacade().removeBizObjects(userId, schemaCode, deleteIds);
		}
		map.put("errorCount", allCount - filterCount);
		map.put("successCount", filterCount == 0 ? 1 : filterCount);
		return this.getOkResponseResult(map, "删除列表数据成功");
	}

	private void asyncFullExport(QueryDataVO queryData, ExportTaskModel exportTaskModel) {
		completionService.submit(() -> {
			try {
				exportDataAsync(queryData, exportTaskModel);
				return exportTaskModel;
			} catch (Exception e) {
				log.error("异常的内容：--{},--{},--{},--{}", e, e.getStackTrace(), exportTaskModel, queryData);
				exportTaskModel.setTaskStatus(ExportTaskStatus.END);
				//exportTaskModel.setUserId(getUserId());
				exportTaskModel.setPath(null);
				exportTaskModel.setEndTime(new Date());
				exportTaskModel.setExportResultStatus(ExportResultStatus.EXPORT_FAIL);
				ExportTaskModel save = getExportTaskFacade().save(exportTaskModel);
				return save;
			}
		});
	}

	private void exportDataAsync(QueryDataVO queryData, ExportTaskModel exportTaskModel) {
		long currentTimeMillis = System.currentTimeMillis();
		String userId = exportTaskModel.getUserId();
		String queryCode = queryData.getQueryCode();
		if (StringUtils.isEmpty(queryCode)) {
			//如果列表编码为空则获取默认第一个列表
			List<BizQueryHeaderModel> bizQueryHeaders = getAppManagementFacade().getBizQueryHeaders(queryData.getSchemaCode());
			queryCode = bizQueryHeaders.get(0).getCode();
		}
		//拿到列表对象，去拿数值数据项的配置信息

		List<BizQueryColumnModel> columns = queryData.getColumns();
		String schemaCode = queryData.getSchemaCode();
		//获取后台配置数据项权限并过滤数据项
		if (CollectionUtils.isEmpty(columns)) {
			log.info("该模型没有可展示数据项");
		}
		permissionData(userId, columns, schemaCode);
		queryData.setMobile(false);
		BizSchemaModel bizSchemaModel = getAppManagementFacade().getBizSchemaBySchemaCode(queryData.getSchemaCode(), true);
		List<BizPropertyModel> propertyModels = bizSchemaModel.getProperties();
		//根据传入的objectIds，为空，导出所有；否则，导出选中的

		Map<String, Map<String, Object>> childNumricalFormat = Maps.newHashMap();
		List<BizObjectModel> bizObjects = null;
		try {
			long bizTimeStart = System.currentTimeMillis();
			bizObjects = searchObjectId(queryData, userId, propertyModels, queryCode, columns, childNumricalFormat);
			childNumricalFormat = getChildNumricalFormat(queryData, userId, propertyModels, queryCode, columns);

			long bizTime = System.currentTimeMillis();
			log.info("查询数据的时间：--{}", bizTime - bizTimeStart);
		} catch (Exception e) {
			log.info("获取数据异常：--{},--{},--{}", e, e.getStackTrace(), exportTaskModel);
			exportTaskModel.setExportResultStatus(ExportResultStatus.EXPORT_DATA_FAIL);
			exportTaskModel.setTaskStatus(ExportTaskStatus.END);
			getExportTaskFacade().save(exportTaskModel);
		}
		parseFilterVo(queryData, bizSchemaModel);
		propertyModels = getAllPropertyModels(propertyModels);
		int size = bizObjects.size();
		log.info("bizObject的数量：--{}", size);
		//处理导出的数据项
		//如果只导出了一页数据就在web处理，否则在engine
		if (CollectionUtils.isNotEmpty(queryData.getObjectIds())) {
			machesProperty(columns, bizObjects, queryData, queryCode);
		}
		List<Map<String, Object>> datas = getDatas(columns, bizObjects, queryData, childNumricalFormat);
		ExportExcelHelper.asynExportData(columns, datas, propertyModels, childNumricalFormat, userId, exportTaskModel, getExportTaskFacade());
		long currentTimeMillisEnd = System.currentTimeMillis();
		log.info("总时间————————" + String.valueOf(currentTimeMillisEnd - currentTimeMillis));
	}

	/**
	 * 获取需要导出的列表数据信息权限，并过滤
	 *
	 * @param userId     登录用户
	 * @param columns    展示字段
	 * @param schemaCode 模型编码
	 * @return void
	 */

	private void permissionData(String userId, List<BizQueryColumnModel> columns, String schemaCode) {
		List<BizPermGroupModel> bizPermGroups = getAppManagementFacade().getBizPermGroupsByUserIdAndSchemaCode(userId, schemaCode);

		if (isAdmin(userId) || isSysManager(userId) || CollectionUtils.isEmpty(bizPermGroups)) {
			log.info("权限组未设置，拥有所有权限!");
		} else {
			List<BizPermPropertyModel> permPropertyModels = bizPermGroups.stream().map(BizPermGroupModel::getPermProperties).reduce(new ArrayList<>(), (all, item) -> {
				all.addAll(item);
				return all;
			});
			Set<String> propertyPermCodes = new HashSet<>();
			//获取所有已配置的数据项
			//查看权限
			propertyPermCodes = permPropertyModels.stream().filter(t -> t.getVisible() && t.getBizPermType().equals(BizPermType.CHECK) && t.getVisible()).map(BizPermPropertyModel::getPropertyCode).collect(Collectors.toSet());
			if (CollectionUtils.isEmpty(columns)) {
				return;
			}
			List<String> propertyTypes = Arrays.stream(DefaultPropertyType.values()).map(DefaultPropertyType::getCode).collect(Collectors.toList());
			propertyPermCodes.addAll(propertyTypes);

			Set<BizQueryColumnModel> newList = new LinkedHashSet<>();
			for (BizQueryColumnModel column : columns) {
				if (propertyPermCodes.contains(column.getPropertyCode())) {
					if (column.getPropertyType().equals(BizPropertyType.CHILD_TABLE)) {
						List<BizQueryChildColumnModel> childColumns = column.getChildColumns();
						if (childColumns != null) {
							for (BizQueryChildColumnModel childColumn : childColumns) {
								if (propertyPermCodes.contains(childColumn.getPropertyCode())) {
									newList.add(column);
									break;
								}
							}
						}
					} else {
						newList.add(column);
					}
				}
			}
			if (newList.size() > 0) {
				columns.clear();
				columns.addAll(newList);
			}

		}
	}
	/**
	 * 拿到实际的业务id，选择全部或者勾选部分
	 *
	 * @param userId    登录用户
	 * @param queryData 展示的列表模型数据抽象
	 * @param
	 * @return void
	 */
	//迭代模式下拿数据
	private List<BizObjectModel> searchObjectId(QueryDataVO queryData, String userId, List<BizPropertyModel> properties, String queryCode, List<BizQueryColumnModel> columns, Map<String, Map<String, Object>> childNumricalFormat) {
		List<BizObjectModel> bizObjects = new LinkedList<>();
		String schemaCode = queryData.getSchemaCode();
		List<String> objectIds = Lists.newArrayList();
		objectIds = queryData.getObjectIds();
		if (CollectionUtils.isEmpty(objectIds)) {
			//如果pag传入为零 且size大于零就分页取
			Integer page = queryData.getPage();
			Integer size = queryData.getSize();
			//用for循环分页拿数据
			Loop:
			for (int i = 0; i < i + 1; i++) {
				page = Integer.valueOf(i);
				size = exportDataPageable;
				queryData.setPage(page);
				queryData.setSize(size);
				Page<BizObjectModel> bizObjectModels = queryExportDatas(userId, queryData, true, true, properties, columns, childNumricalFormat);
				long total = bizObjectModels.getTotal();
				double s = size.doubleValue();
				double t = total / s;
				double ceil = Math.ceil(t);
				int c = (int) ceil;
				boolean equals = c == (i + 1);
				List<? extends BizObjectModel> content = bizObjectModels.getContent();
				if (CollectionUtils.isEmpty(content)) {
					break Loop;
				}
				bizObjects.addAll(content);
				if (equals) {
					break Loop;
				}
			}
		} else {
			objectIds = queryData.getObjectIds();
			if (CollectionUtils.isNotEmpty(objectIds)) {
				Iterator<String> iterator = objectIds.iterator();
				while (iterator.hasNext()) {
					String objectId = iterator.next();
					BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(userId, schemaCode, objectId);
					BizObjectModel bizObjectModel = bizObject;
					bizObjects.add(bizObjectModel);
				}
			}
		}
		return bizObjects;
	}

	/**
	 * @param queryData
	 * @param userId
	 * @param properties
	 * @param columns
	 * @return
	 */
	//迭代模式下拿数据
	private Map<String, Map<String, Object>> getChildNumricalFormat(QueryDataVO queryData, String userId, List<BizPropertyModel> properties, String queryCode, List<BizQueryColumnModel> columns) {
		Map<String, Map<String, Object>> list = null;
//        List<String> objectIds = Lists.newArrayList();
//        objectIds = queryData.getObjectIds();
//        if (CollectionUtils.isEmpty(objectIds)) {
		//如果pag传入为零 且size大于零就分页取
		Integer page = queryData.getPage();
		Integer size = queryData.getSize();
		//用for循环分页拿数据
		Loop:
		for (int i = 0; i < i + 1; i++) {
			page = Integer.valueOf(i);
			size = exportDataPageable;
			queryData.setPage(page);
			queryData.setSize(size);
			list = queryChildNumricalFormat(userId, queryData, true, true, properties, columns);
			break Loop;
		}
//        }
		return list;
	}

	/**
	 * 处理数据项类型
	 *
	 * @param queryData
	 * @param bizSchema
	 */
	private void parseFilterVo(QueryDataVO queryData, BizSchemaModel bizSchema) {
		if (CollectionUtils.isNotEmpty(bizSchema.getProperties())) {
			Map<String, List<BizPropertyModel>> listMap = bizSchema.getProperties().stream().collect(Collectors.groupingBy(BizPropertyModel::getCode));
			if (CollectionUtils.isNotEmpty(queryData.getFilters())) {
				for (FilterVO filterVO : queryData.getFilters()) {
					if (filterVO.getPropertyType() == null) {
						filterVO.setPropertyType(listMap.get(filterVO.getPropertyCode()).get(0).getPropertyType());
					}
				}
			}
		}
	}

	//子表属性
	private List<BizPropertyModel> getAllPropertyModels(List<BizPropertyModel> bizPropertyModels) {
		List<BizPropertyModel> propertyModels = Lists.newArrayList();
		for (BizPropertyModel bizPropertyModel : bizPropertyModels) {
			if (BizPropertyType.CHILD_TABLE.equals(bizPropertyModel.getPropertyType())) {
				if (bizPropertyModel.getSubSchema() != null) {
					propertyModels.addAll(getAllPropertyModels(bizPropertyModel.getSubSchema().getProperties()));
				}
			}
			propertyModels.add(bizPropertyModel);
		}
		return propertyModels;
	}
}
